textmachine/docs/PROGRESS.md

448 KiB
Raw Blame History

Журнал прогресса

⟶ ТЕКУЩЕЕ СОСТОЯНИЕ (на 2026-09-07, голова D39.224 — КУРС: движок и платформа до «работает и отдаёт результат», фронт ЗАМОРОЖЕН и P7 его НЕ размораживает (D39.147). ОЧЕРЕДЬ №23 (единственный носитель — здесь; роль передана 06.09, №22 закрыт нотой передачи D39.217; ⚠ испр. 06.09: коммит передачи c992ee5 бампнул голову и НЕ тронул номер — гейта на номер очереди нет вовсе, counts.py сверяет только голову, поэтому носитель разошёлся молча). ⚠ ЗАКАЗ ВЛАДЕЛЬЦА 01.09 — ПЕРВЫМ: (0а) ревизия документации на ПРОТУХШЕЕ — по всем зонам, не только тронутым; (0б) планы доработок в БЭКЕНД и ПЛАТФОРМУ по остатку бэклога и регистра; (0в) вынос неактуального в АРХИВ (docs/archive/, platform/docs/archive/) — за сутки 31.08 закрыто много, и часть носителей стала историей. ⚠ Трезвость по масштабу (пере-считано 02.09): 90 живых дока в docs/ (пере-счёт 04.09: find docs -name '*.md' -not -path 'docs/archive/*' | wc -l), 8 в platform/docs, 9 в backend/docs — ⚠ из 94 ВРЕМЕННЫЙ остался ОДИН (DOC_CLEANUP_PLAN, живой до закрытия батчей Б14/Б15/Б17); два прежних временных уехали в archive/reports/ 02.09; счёт бэклога — бюллетенем ниже, открытых рядов регистра платформы — 112 (major 3), всего рядов 465 (пере-счёт python3 docs/scripts/counts.py; с 04.09 оба числа под гардом --check, прежние 95/3 разошлись молча) ⚠ (ревизией 02.09 ряды 154 и 157 переведены из «скоро» в «когда-нибудь»: их гейтом стоял первый холодный прогон, он ОТРАБОТАЛ 31.08 и оба предусловия оказались другими — разбор в самих ячейках, ни одна НЕ закрыта). ⚠ Числа доков counts.py НЕ сторожит — при переносе файлов пере-считывать руками командой find docs -name '*.md' -not -path 'docs/archive/*' | wc -l. ⚠ И предупреждение о МЕТОДЕ, купленное сменой №21: «выглядит протухшим» ≠ «протухло». Три факта оркестратора опровергнуты ЗАМЕРОМ сессий, а якоря 15-money-path.md в девяти случаях из двенадцати РОДИЛИСЬ верными и сгнили дрейфом — то есть ревизия обязана быть исполнением, а не чтением. ⚠ ОЧЕРЕДЬ, унаследованная от №21 (три лендинга 31.08 — секция «СОСТОЯНИЕ ПАКОВ» ниже): (1) РАЗРЫВ ЦИКЛА ЗАМКНУТ ЖИВЬЁМ 04.09 — пользователь получил EPUB настоящего ПЛАТНОГО перевода ЧЕРЕЗ API, epubcheck 5.3.0 на СКАЧАННОМ файле 0/0/0/0 (книга bk_SS5VES2JELESJSTR, потрачено $0.278319 из гранта $0.60 при потолке пака $1.5, санкция D39.189). Дверь выдачи построена и проверена исполнением: 202+Location, поллинг с Retry-After, Range 206 · второй клиент 200 · аноним 401 · чужая книга 404, TTL с GC, идемпотентность третьего создающего вызова. Все ТРИ сценария строки 216 предъявлены живьём (подпись банка · halt на потолке с exit 4 · 409 run_not_resumable/ceiling_reached и лечение новым прогоном). ПЯТЬ ПОТОКОВ РАБОТЫ — состояние на 07.09 (пере-снято лендингами смены №23). (1) ПОЛИГОН — «ремонт прибора» (docs/POLYGON_INSTRUMENT_REPAIR_SESSION_PROMPT.md, строки 319 · 300 · 265 · 143): ⚠ ЕДИНСТВЕННЫЙ ПОТОК, НЕ СДВИНУВШИЙСЯ ЗА СМЕНУ — сессия по промту так и не стартовала. Блокирующая линза слепого чтения меряет верность ЧЕРНОВИКУ, а судимой руке предписано отходить от него по исходнику (D39.215 п.3) ⇒ фаза Д ПРИОСТАНОВЛЕНА до его лендинга: иначе покупаем числа, которые ничего не значат. (2) БЭКЕНД — «закон банка честно»: ЗАЛЕНДЕН 07.09, акт D39.222 (5092ae3 + 0ae9e8a + bc03fc0). Строки 267 и 318 закрыты, у 320 исполнена половина (а). Шесть кругов самопроверки, 43 находки в собственной работе. Живой остаток зоны — строки 333339 (шов-близнец и пять описаний, лгущих оператору) и 320(б). (3) ПЛАТФОРМА — «деньги и правда»: ЗАЛЕНДЕНА 07.09, акт D39.221, контрактный минор 0.13.0 (fda0679 + 3d90943). Строки 285 · 305 · 325 закрыты. ⚠ Синхронный разрез приёма принят ПОСТРОЕННЫМ, НО НЕ ГОТОВЫМ — сработало правило остановки (9 major из 11 в одном механизме), десять пунктов несёт строка 332; ложный инвариант бюджета заландён осознанно (окно лжи 8 секунд при дефолте в 16 минутах, ломается идемпотентность). (4) ДИЗАЙН-ПАК 161 — НАПИСАН 07.09 (docs/CHAPTER_STRUCTURE_DESIGN_SESSION_PROMPT.md, 7f84c8d), прошёл оба рубежа. ⚠ НЕ ВЫДАН: новый пак идёт НОВОЙ сессии, обе ночные отработали — запуск за владельцем. (5) ТЕХДОЛГ БЭКЕНДА — разбор research/33 в трекер: ЗАЛЕНДЕН 07.09, акт D39.224. Заведены строки 344350, дописки в 86/114/119/182/224; «переписать» не получил ни один из одиннадцати долгов. Ратифицированы ПОРЯДОК (шаг 0 параллельно дизайну 161 → шаги 2+3 ОДНИМ окном перенарезки, wire-очередь 182 ложится в него же → шаг 4 аддитивно) и ФОРМА запретов (жёсткие — только под ратифицированной базой, прочее — условия с механизмом, чтобы не спорить с дизайн-паком). ⚠ Пак шага 0 ещё НЕ НАПИСАН — это $0 и снапшот-нейтрально (строки 344 · 345 · 346(а) · 349, плюс пины порядка из дописки 224); он и есть следующий ход по этому потоку. ЧТО ЖДЁТ СЛОВА ВЛАДЕЛЬЦА, поимённо: строка 340 — сужение входа действует только на синхронной ветви, при деплойном классе книга одним полотном попадает в библиотеку МОЛЧА, и закрыть нечем без пятой причины отказа (source_unreadable терминален и УДАЛЯЕТ исходник) · строка 326 — критерия впуска в дереве нет, консьерж против самообслуживания · обязательный ВТОРОЙ круг селф-ревью (первая половина того же слова подтверждена как РЕКОМЕНДАЦИЯ, D39.220; вторая не подтверждена, улика в её пользу — ниже в этом же листе). ⚠ Зоны параллельны по норме проекта; ограничение — пропускная способность ПРИЁМКИ оркестратора: сериализуй ЛЕНДИНГИ, не старты. ⚠ Зеркало фронта — 0.2.3 против канона 0.13.0 (одиннадцать миноров), зона заморожена. ПОЧИНЕНО 05.09 ЛЕНДИНГОМ 616a8e4 (пак «денежный стоп», акт приёмки D39.206; ⚠ испр.: раньше здесь стояла D39.203 — это нота ВЛАДЕЛЬЦА про «сколько добавить», а не акт) — ниже до-паковая археология, читать как историю. Отказ резервации больше не роняет волну: он ЗАЩЁЛКИВАЕТ её (новое не стартует, допущенное дорабатывается), а обязательный вызов ЖДЁТ settle, когда settle может помочь. ⇒ порог «книга короче десяти глав не переводится» СНЯТ; остаточный пол — одна резервация (~$0.07 ≈ 3 главы), и он ВЫВЕДЕН, а не замерен (замер — $0.15-прогон пятиглавой книги, передан полигону). ⚠ Разбор эрратой — architecture/15-money-path.md, греп ЭРРАТА 05.09. ⚠ Эта строка сутки стояла непоправленной ПОСЛЕ лендинга и по ней оркестратор предупредил владельца о снятой стене как о действующей — канон, не обновлённый лендингом, врёт громче отсутствующего. НО КНИГУ ЧЕРЕЗ API НЕЛЬЗЯ БЫЛО ДОВЕСТИ ДО КОНЦА — найдено прогоном 04.09 и воспроизведено дважды. Прирост потолка на прогон = chaptersLeft × $0.03 (ставка DefaultPerChapter, занижена ×4.47 — D39.179 п.1), и после первой готовой главы это $0.27, тогда как движок при waves.workers: 4 резервирует под редакторский шаг ~$0.28 ⇒ отказ резервации, прогон встаёт, книга не двигается. Два прогона подряд дали одно и то же: committed не сдвинулся, холд вернулся. ⇒ занижение ставки — не «шкала короче», а СТОП ПРОДУКТА: с какого-то момента каждая следующая покупка не покупает ничего. Лечить придётся согласованно двумя сторонами (ставка платформы + резерв движка под шаг с параллельными воркерами), носитель — ряд регистра зоны, вес major за недостижимость продукта, а не за деньги: сам стоп НЕ ЖЖЁТ ничего — замер платформы 04.09 показал отмену ДО ухода запроса (латентность 2031 мс, model_actual пуст, токенов ноль), и вся книга сходится до микро-доллара по трём источникам (request_log 0.278319 · spend.committed_usd 0.278318752 · платформенный committed 278319 микро). ЗАТО HALT НА ПРОГОНЕ, КОТОРЫЙ ПРОДВИНУЛСЯ, ЖЖЁТ — отдельная находка того же прогона и свежая датированная точка строки 78 («леджер = НИЖНЯЯ граница»). Четыре редакторских вызова ушли параллельно; один дошёл ($0.063404) и своим коммитом сорвал потолок, три других отменены в тот же миг, отработав 120756, 156469 и 156470 мс — и легли в леджер нулём. Незаписанное ≈ $0.050.19 на ОДИН halt против $0.278 за всю книгу, то есть механизм, защищающий от перерасхода, сам создаёт неучтённый расход. ⚠ Списание провайдером НЕ доказано (биллинга у нас нет) — утверждается ровно наблюдаемое: вызовы шли 22.6 минуты, их цены в леджере нет. ⇒ Дыра НЕ в принципе, а в покрытии, и это делает её заказом, а не наблюдением (разбор оркестратора 04.09 по коду): консервативная оценка уже построена и ратифицирована — backend/internal/pipeline/stagerun.go, греп settling the reservation estimate to keep the ceiling honest (pack-13 point-9), — но её условие требует ОТВЕТА провайдера (resp.Usage), а отменённый в полёте вызов ответа не получает и уходит другим путём. Направление лечения: сеттлить оценку при отмене вызова, который успел уйти; различитель — факт ухода (латентность кандидат, порог обязан быть обоснован замером, а не назначен). Половина ДВИЖКОВАЯ. ⚠ Прежняя формулировка пункта — ниже, она о состоянии ДО 04.09. Движок пишет файл с 30.08 (tmctl build — EPUB 3 + чистый txt, D39.175), и холодный прогон 31.08 предъявил это живьём: собранный EPUB настоящего перевода прошёл epubcheck 0/0/0/0 и передан владельцу. ⚠ ЭТОТ АБЗАЦ ЗАКРЫТ 04.09 и оставлен как история: дверь выдачи ПОСТРОЕНА и заленджена (adf5e53, D39.194), смонтировано 18 операций из 21 (три адреса двери: createExport/getExport/downloadExport), долг П-17 зона пере-сняла. Прежняя проверка «grep -rn 'createExport\|getExport' platform/internal/ — пусто» БОЛЬШЕ НЕ ПУСТА и как гейт не работает. Не смонтированы по-прежнему getRun, updateBook, deleteBookupdateBook несёт продуктовое следствие, строка бэклога 274 (имя книги в выданном файле не чинится ничем). Слово «отдаёт результат» ложно по букве ТОЛЬКО платформенной половиной (п.4) · (2) холодный прогон движка ОТРАБОТАЛ 31.08, закрыт РЕШЕНИЕМ ВЛАДЕЛЬЦА «не доводить» (отчёт — archive/reports/COLDRUN_V16_REPORT_2026-08-31.md, числа относятся к 065d8ac). Потрачено $0.436110 из санкции $0.80. ПРЕДЪЯВЛЕНО живьём: объёмный потолок · D39.158 ОБЕИМИ половинами (стоп и не-стоп) · exit 16 · строки 154/198/239/240. ⚠ Причина большой доли редактора НЕ УСТАНОВЛЕНАУСТАНОВЛЕНА пробой полигона 02.09 по четырём осям: РЕДАКТОР ДУМАЕТ, А НЕ ПИШЕТ. Размышление — 77.9% цены редактора без ручки и 45.7% с low; у glm-5 с выключенным thinking — 0.0%. Замер куплен и закончен ($6.17 из $9.50). ⚠ research/30 §2.4 того же полигона повторяет «причина не установлена» — это про ДРУГОЙ вопрос (доля роли в прогоне против доли размышления в цене роли), и различение обязано попасть в ревью-шапку 30. Доля редактора идёт с ДВУМЯ знаменателями: 49.3% от всего прогона ($0.214865 из $0.436110) и 81.3% внутри порции П1 (⚠ ходившее «73%» — фантом, в отчёте его нет ни разу). Следующий шаг — контролируемая проба по ЧЕТЫРЁМ осям (роли осей и три требования, купленные ошибками этого прогона, — §14 отчёта; ось stale НЕДОСТИЖИМА — §10 там же). ⚠ Цена: слово владельца 31.08 — ≈$0.60, потолок $0.80, ДЕСЯТЬ глав ПОЛНОЙ цепью включая редакторскую волну.КЛЮЧИ: гейт снят словом владельца 30.08, разбор двух путей — D39.176 п.6. Живое отсюда: конвенционного .env НЕТ НИ У ОДНОЙ книги корпуса (заполнены только projects/textmachine/backend/.env и .../eval/.env), поэтому прогон движка обязан передавать --keys-file абсолютным путём и только на translate; для п.3 нужен ДРУГОЙ файл — TM_PLATFORM_ENGINE_KEYS_PATH, тоже АБСОЛЮТНЫМ путём (platform/internal/config/config.go, греп must be an absolute path). Лечение операционное и $0 — направить переменную на уже заполненный файл; проверять ПРОГОНОМ, не чтением (гардрейл .env) · (3) живой сквозной прогон через API платформы — форма манифеста, сайдкара банка и карта причин флагов сочинены платформой САМОСТОЯТЕЛЬНО. ⚠ Уточнено 01.09: гейт СНЯТ холодным прогоном, и настоящие артефакты движка теперь ЕСТЬ (каталог books/gu-zhenren/coldrun-v16/), но сверка вышла ТОНКОЙ: на шов реально вышло одно значение flag_reason из пятнадцати (sanitizer_stripped), остальные четырнадцать по-прежнему только чтением кода, а манифест против platform/internal/ingest/manifest.go не сверялся вовсе · (4) дверь выдачи — строго ПОСЛЕ (3) (⚠ слово владельца 30.08: дверь ВСЕГДА строит файл — отказ юзеру не отдаётся, неполная книга уходит с пометкой, т.е. дверь зовёт tmctl build --partial; отказ по умолчанию остаётся операторской ручкой CLI; D29.1(б) «fail-closed» читать как «никогда молча» — честность несут пометки) · (5) проводка --max-units — снятие гейта, а не стройка: механизм в движке стоит (D39.170), живое основание гейта — PD-422 · (6) разморозка фронта — ПОСЛЕ (4): зеркало отстало на ВОСЕМЬ миноров (frontend/docs/api-contract/openapi.yaml0.2.3 против канона 0.10.0, и первый из них — ЛОМАЮЩИЙ 0.3.0), 16 операций против 21; зеркало последний раз двигали 15.08 — ⚠ ходившее «30.08» было взято из текста коммита, а не из git log (испр. 05.09), то есть расхождение старше на две недели; отставание ратифицировано D39.142 п.5 на время фриза и две ручки разъехались, размораживать раньше значит перегенерировать типы дважды. ⚠ ДВА ЗАГЕЙЧЕННЫХ ТРИГГЕРА НАЖАТЫ И НЕ ОТРАБОТАНЫ — строка бэклога 237 (go.work · вендор-сверка эффорта deepseek-v4-pro; реестр 13-tech-debt-anchors.md §Б-108). ⚠ Состояние git — снимать КОМАНДАМИ, не чтением (ветка polygon ушла вперёд, коммит здесь не цитирую): работа полигона лежит на ней и в main НЕ влита, а git status -- eval/ в main-дереве пуст ПО ПОСТРОЕНИЮ и уводит в ложный вывод «работы нет»; ⚠ «развязка git с origin» — арбитр ПЕРЕ-СНЯТ 04.09 и прежний вердикт БОЛЬШЕ НЕ ВЕРЕН: git merge-base --is-ancestor origin/main mainrc 1, git log main..origin/mainafa7700 temp (коммит владельца 04.09, которым он передавал работу зон). Локальная линия ушла вперёд на семнадцать коммитов и содержит ВСЁ содержимое afa7700 — оно снято reset --soft и заленджено раздельными зонными коммитами, — но формально ветки разошлись. Лечение — force-push рукой владельца; не пуллить (его же правило). ⚠ Пункт «развязка git с origin» в листе владельца ниже держится ТОЛЬКО как вопрос про force-push его рукой; утверждением о расхождении дерева он не является — арбитр этой пары именно здесь.

  • Норма приёмки, купленная аудитом D39.167 п.1: акт лендинга, объявивший закрытие строки регистра или бэклога, обязан быть СВЕРЕН СТАТУСОМ в тот же заход — иначе следующий пак собирается ПО РЕГИСТРУ и едет чинить построенное. Машинная половина — строка бэклога 225.
  • ЛЕНТА КОНТРАКТНЫХ МИНОРОВ (что принёс каждый — телом ноты): 0.5.0 — D39.161 · 0.6.0 — D39.162/D39.163 · 0.7.0 — D39.166 · 0.8.0 — D39.169 · 0.9.0 — D39.180 · 0.10.0 — D39.194 (дверь выдачи: downloadExport, failure_code словарём, Export.url относительный; ⚠ читать с эрратой 04.09-в — минор был ратифицирован без своей кодовой половины и сутки жил ложным на проводе). Прожитые дампы приёмок P9/P10 — archive/PROGRESS-2026-08-backend.md и тела нот.
  • ЖИВОЕ: полигон — фаза Д ИДЁТ (заказ 10.08; деньги санкционированы 15.08 напрямую полигону — ⚠ числа потолка в носителях расходятся, фактическую цепь сверить при лендинге петель; ja-книга enkan_no_hate_ja; при ратификации фазы Д в D-ноту: декой-правило + обязательный кросс-семейный опровергатель приёмки — одобрены 10.08; свежие фриз-коммиты полигона в дереве — НЕ трогать) · платформа и контракт — статус в строке выше, здесь НЕ дублируется (один носитель на факт) · фронт ЗАМОРОЖЕН (D39.136 п.2 + D39.147: морозится ДАЛЬШЕ лендинга P7 — слово владельца 17.08; P7 зону НЕ размораживает, S5-промт не выдаётся, разморозка отдельным словом по достижении сквозного пути; перечень первого касания зоны — синк зеркала на ТЕКУЩИЙ канон (отставание и его цена — п.6 очереди выше и строка бэклога 183(б)) + перегенерация типов + моки + гейт утечки конвейера + ФС-1..12 + Ф-63/Ф-28 + фразы В-11 по словарю кодов — не отменён, ждёт разморозки) · закрытые стройки эры — реестром нот architecture/05-decisions-index.md (D39.130137, одна строка на ноту).
  • Открыто на владельце:НОВОЕ 06.09: второй круг селф-ревью — бэкенд-сессия передала слово владельца «после сдачи обязателен селф-ревью, и если он дал исправления — НОВЫЙ круг, проверяющий исполнением и исходный заказ, и закрытие находок предыдущего круга». Первую половину того же слова (комментарии) он подтвердил как РЕКОМЕНДАЦИЮ, про вторую не сказал ничего; в мандате самопроверки CLAUDE.md сегодня описан ОДИН круг. Сессии исполняют добровольно, каноном не стало. УЛИКА В ПОЛЬЗУ ПРАВИЛА, снятая в ту же ночь 07.09: круг 2 бэкенд-сессии опроверг ЕЁ ЖЕ правку круга 1 — свёртка сравнения через NormalizeSourceKey вводила ЛОЖНООТРИЦАНИЕ (замер зоны: ReplaceGlossary(族長 + 族长)rows stored=2, контроль на байт-равном srcUNIQUE constraint failed, то есть UNIQUE стоит на СЫРОМ src и обе строки инжектятся), и мутация «свернуть сравнение» до круга 2 ПЕРЕЖИВАЛА весь пакет. Один круг сдал бы тихо-зелёное. · Развилка строки 291 ЗАКРЫТА владельцем 05.09 — D39.204: отказ резервации на ретрае деградирует во ФЛАГ («пусть флагает просто как-то»); вариант «минимальная покупка ≥ step_max_usd» снят. ⚠ Это оказалось НЕ сменой канона: D2 уже кончается флагом, денежная ветка до него не доходит. · Лестница D25.1 ЗАКРЫТА владельцем 05.09 — D39.205: копия БЕЗ пометки = книга БЕЗ ЕДИНОГО ПРОПУСКА; любой пропуск ⇒ пометка в файле, гранулярность — ЮНИТ (пропущенный кусок главы критичен). Имя файла решено паком 7e2226a (вычисляется при скачивании). ⚠ Прежняя редакция держала это открытым на владельце — по ней он и получил вопрос, который сам уже закрыл · лейбл главы без заголовка (сейчас цифры; словесный шаблон = одна строка reader.txt после ратификации К-3) (⚠ три вопроса пака ЗАКРЫТЫ словом владельца 30.08: экспорт юзеру — всегда строить, см. п.4 очереди · модель пометок подтверждена как построена — надпись о пропуске в файле, отдельный варнинг-слой в интерфейсе НЕ строим, машинный отчёт сборки остаётся внутренним носителем (дрейф) · RTL — снят до появления право-налевой целевой пары) · ⚠ ПЛАТФОРМЕННЫЙ ЛИСТ ЗАКРЫТ СЛОВОМ ВЛАДЕЛЬЦА 30.08 — четыре ответа и их следствия ЦЕЛИКОМ телом D39.176 (квот нет · продажа не в бете · продолжение после пополнения — руками · фразы пользователя делегированы проекту с требованием интернациональности). ⚠ Лист ПУСТ: последний его пункт (PD-421, «держит ли открытый поток сессию живой») СНЯТ замером 30.08 — окно бездействия сессии 14 суток, абсолютный срок 30 (platform/internal/config/config.go:339=defaultSessionIdle), скольжение окна идёт на любом аутентифицированном запросе, а поток теряется лишь после того, как подметён протухший ряд, то есть после ДВУХ НЕДЕЛЬ без единого действия пользователя. ⚠ Часовой интервал в этой теме — периодичность УБОРКИ, а не срок сессии (эррата 30.08-а к D39.176 п.5) · ⚠ Гейт словаря фраз — строка 204 (D39.176 п.4). ⚠ Прежний указатель «строка 148» мёртв — строку удалил a023e39 решением владельца, восстанавливать Приложение А по ней НЕ надо · развязка git с origin (локальная линия ИСТИННА, force-push его рукой; не пуллить) · В-4/Ф-30 (глава без заголовка — движковая половина строка 160) · мини-проба флора 44 (одобрена, промт не выдан; число — после ре-пробы 188) · подпись денежного шага 46 (ратифицирована D39.190 п.4: пере-снапшот батча — единым актом, цена сегодня $0) · схема time-based DeepSeek — рекомендация и её доводы строкой 172(а) · вход ратификации фазы Д: посылка «dspro дешевле glm» в пике ПЕРЕВЁРНУТА (×1.26 дороже, D39.137 п.4) · возражение Sol по проходу tier эксп-23 (довод дословно — слайс archive/PROGRESS-2026-08-10-15.md: Sol судил СВОЁ семейство, что запрещено D13.3; подтвердить или снять — при лендинге петель фазы Д) · фронт-вопросы зонного журнала: В-7 (плотность; держит Ф-54) · В-8 (слово состояния в дереве) · В-9 (языки интерфейса — механизм готов, ПТ-36) · Ф-38 (вкладка «Замечания»). Закрытые пункты листа — в нотах D39.136145, здесь не держатся.
  • Сделано (сводно) — снимок ленты закрытых эр в archive/PROGRESS-2026-08-04-09.md; детали — D-лог и слайсы.
  • КУРС НА 04.09 — ПОРЯДОК РАБОТ, СОБРАННЫЙ ВЕЕРОМ ПО ВСЕМУ БЭКЛОГУ (31 агент, 46 кандидатов, шесть срезов + опровергатели + критик полноты). ⚠ Главный результат метода, а не списка: из 46 кандидатов бэклога опровержение пережили ДВА — остальное трекерная инерция; а то, чего в трекере не было ВОВСЕ, оказалось тяжелее всего, что в нём есть (строки 269275, заведены этим же заходом). Порядок: (1) ЭКСПЛУАТАЦИЯ — ЗАКРЫТА ЛЕНДИНГОМ 05.09 (7e2226a + 3e84716, акт D39.201): бэкапы с ПРЕДЪЯВЛЕННЫМ восстановлением, дверь для не-браузерного клиента, имя книги. Строки 269 · 270 · 274 закрыты и сняты из таблицы; ниже — история заказа. Строка 269 бэкапов нет ни у оплаченной работы, ни у денежного реестра — ЕДИНСТВЕННАЯ находка дня без частичного исхода: одна потеря диска необратима и недоказуема · строка 270 у продукта НОЛЬ дверей: bearerToken объявлен и не выдаётся, живой цикл 04.09 прошёл через dev-вход, который прод отказывается запускать, фронт заморожен · строка 274 имя книги в выданном файле исходноязычное и не чинится ничем (дёшево, а ломается первое, что видит человек). (2) ДЕНЬГИ И ЕДИНИЦА ЗАКАЗА — РЕШЕНО 04.09 во ВТОРОЙ редакции, строки 276283: заказ это ОБЪЁМ, объём меряется ЗНАКАМИ ИСХОДНИКА ПО ЮНИТУ (движок публикует в манифесте), «страница» — их отображение и её размер это ДАННЫЕ ЛОКАЛИ; вердикт ДО клика, сумму человек не выбирает. ⚠ Первая редакция мерила ГЛАВАМИ и пала: глава надёжна в одном случае из трёх, дыру нашёл владелец. ⚠ Тем же вопросом вскрыта ВТОРАЯ ненадёжная единица — character_count считает байты файла (для EPUB — zip) и подписан у пользователя «Знаков», строка 282. ⚠ ФОРМА ЗАКРЫТА РЕШЕНИЕМ ВЛАДЕЛЬЦА 05.09 (D39.196): баланс — ДЕНЬГАМИ и виден, ползунок потолка — деньгами, второй ползунок объёмом (главы если распозналось, знаки если нет), старт = холд. Запрет «денег в UI» ОТОЗВАН владельцем; ждать от него больше нечего. Разбор трёх независимых чтений в architecture/15-money-path.md §«ОТКРЫТАЯ РАЗВИЛКА 04.09»; PD-440/PD-441. Смена единицы — амендмент D39.84, объявленный требующим отдельного слова ещё при вписании глав (D39.110 п.2а, «добор оркестратора»); сам владелец 28.08 назвал нынешнюю ручку «денежной ручкой с подписью главы» (D39.165 §1). ⚠ Смена единицы БЕЗ «сказать, когда кончилось» ухудшает продукт: стена перестаёт быть свойством книги и становится свойством ввода, то есть встречается ПЕРВЫМ действием, а не в конце. (3) ДЫРА ЧЕРЕЗ ПОЛЬЗОВАТЕЛЬСКУЮ ДВЕРЬ — ЗАКРЫТА ЛЕНДИНГОМ 05.09 (81a89e9, акт D39.206): граница internal/membank/wirefence.go, три точки исполнения, инвариант снова выполняется КОНСТРУКЦИЕЙ. Строка 271 закрыта и снята; ниже — история заказа. Строка 271: правки банка едут в system-сообщение дословно, а ратифицированный инвариант «untrusted DATA, никогда инструкции… выполняется КОНСТРУКЦИЕЙ» конструкцией больше не выполняется. Дёшево, и обязано быть закрыто ДО первого внешнего пользователя. (4) КАЧЕСТВО — ЦЕЛЬ №1. ⚠ ФОРМУЛИРОВКА «НЕ МОЖЕТ СТАРТОВАТЬ» БЫЛА НЕВЕРНА И СНЯТА ВЛАДЕЛЬЦЕМ (D39.198 п.5, испр. 05.09): из четырёх названных гейтов (24 · 13а · 55 · 149) ТРИ сняты его словом, четвёртый гейтом не был. Живое здесь другое и оно в строке 275: приоритет назван — (1) 100% консистентность · (2) отсутствие выдумок · (3) художественность, и он говорит не о весах рубрики, а о том, ЧЕЙ ОТКАЗ ОСТАНАВЛИВАЕТ ВЫПУСК. Классы дефектов привязываются к УЗЛАМ (банк · редактор · черновик), а не сливаются в одно взвешенное число: оно не диагностирует. ⚠ Дорогое расхождение здесь остаётся, но НЕ то: приоритет №1 сегодня кодом НЕ исполняется — доки держат порог 98%, glossary_miss отгружается флагом ранга 5, а приоритет №2 носителя не имеет вовсе (строка 286). (5) ВТОРАЯ ПАРА ЛОМАЕТСЯ МОЛЧА — после (1)(4), пока пара одна, цена ошибки нулевая. Строка 272 шаблон книги один на все пары и раздаёт КАЖДОЙ книге transcription: palladius · строка 273 пар-шов асимметричен: нет промптов — падает громко, нет целевых ДАННЫХ — выключается молча ВМЕСТЕ С БАНКОМ, то есть книга переводится целиком за полные деньги без механизма консистентности · строки 258/259 через раннер нет ни одной фикстуры с не-ru целью, латинописьменной цели в репо нет вовсе. ⚠ Что веер НЕ менял: горизонт (ДОБОР ИДЕАЛА → вторая пара → МАСШТАБ → пилот → ридер-IDE) остаётся тем же; переставлен ПОРЯДОК ВХОДА в него, и вход теперь эксплуатационный, а не качественный — потому что пускать пользователя некуда и нечем страховать.
  • Курс: этапы ОБЩНОСТЬ · КАЧЕСТВО БАНКА · ПАКЕТ-ЧЕКЕРОВ · ФРОНТ-ЭРА · шов/платформа/движковые блокеры — ПРОЙДЕНЫ (D39.59123). Хвосты курса живут строками: 16 (полная цена холодного старта; edit-волна на малых прогонах отработала и оплачена — 58 вызовов волновым драйвером 2325.07 плюс 648 до драйвера, счёт по леджерам ~/books/gu-zhenren/**/*.db) · coldrun-b фаза C заморожена чекпойнтом легитимно (D39.86; эталон денег/поведения — coldrun-a, read-only); развилка 0731 решена и исполнена (D39.87/91, код 553f1a3).
  • Горизонт (D39.62/67, освежён D39.95): ДОБОР ИДЕАЛА (первым прогоном: оси голоса 24 · авто-режим · цена 16; остаток арбитража банка = рецензент спорных кластеров при ре-пробе — D39.102). ⚠ Испр. 05.09 (D39.198 п.5): прежняя редакция держала здесь ТРИ предусловия, снятых владельцем, — жильцы ролей (149: разморозка ничего не разблокирует, пока идут доработки) · веса K1K12 (13а: веса не нужны, мерить по узлам) · вне-претрейн чекпоинт (55: прогоняем на тех же текстах, оговорка — ограничение ВЫВОДА, а не требование новой книги) → ВТОРАЯ ПАРА живьём (ja→ru; преп 81) → МАСШТАБ → пилот Ф2.5 (гейт резюме-строки 80; строки 6268, 85) → Ф3 ридер-IDE (6971). Стоячие: ToS-триггер 25.10 · Ш-2 до go1.27 (⚠ + x/text Unicode 17 тем же тулчейном — строка 119, реестр §Б-108 справочника якорей) · платные прогоны разблокированы (проба провода — D39.97, конфиги 112 залендены).
  • Стек (полная карта роль→модель→конфиг→квирки — STACK.md, D39.126): draft deepseek-v4-flash thinking-ON low ⚠0731 → терминолог (та же модель) → editor deepseek-v4-pro БИЛИНГВ ИНТЕРИМ (топология ПОДТВЕРЖДЕНА при неразличимости жильцов — D39.117; закон-блок ОБЯЗАТЕЛЕН и ВНЕСЁН — D39.104 п.2, вайр-батч принят D39.199; glm-5 резерв; вахта маппинга эффорта pro — §Б-108) → судья gemini (Ф2, в движке НЕ построен — строка 33); канал B Mistral+grok; ~$0.85/ранобэ (D30.4) — ⚠ ТРИГГЕР ПЕРЕ-КАЛИБРОВКИ СРАБОТАЛ 31.08 (испр. 02.09): платный прогон отработал и дал собственную оценку движка projected_book_usd = 1.1377277707 на десяти главах при куплённых $0.436110; число D30.4 держать как июльское. ⚠ Вендор-факты 1315.08 (пере-пин ИСПОЛНЕН и ПРИНЯТ, D39.137): таблица цен запинена ПИКОМ (flash 0.44/1.32 · pro 1.32/3.96/кэш-хит 0.044 за 1M; счёт шиппинг-c1 = 100% DeepSeek ⇒ ×4.24.4 в пике / ×2.12.2 в долине — замер по трём прогонам); ⚠ испр. 05.09: носители про эффорт pro БОЛЬШЕ НЕ ПРОТИВОРЕЧАТ — и квирки (§3г), и STACK.md говорят одно: ручка ДОХОДИТ до модели с вендор-апдейта 13.08. Живой остаток один — вендор-сверка маппинга и ВЕЛИЧИНА эффекта, строка 237(б); ⚠ ВЕСА pro сменились под тем же слагом (V4-Pro-0813, класс D39.61) — вахта-риг готов (остаток 172); покупки фазы Д на deepseek до 16.08 16:00 UTC — по старым ценам. ⚠ ВЕСЬ банковый контур (банкнота+терминолог+классификатор) ВКЛЮЧЁН в shipping-c1 с b8154cdenabled: true у обоих гейтов и classify_types: true, бюджеты по $1.00 (прежде жил только ран-локальным конфигом книги; строка 140 — его единственный вход mining.contrast_path в git ОТСУТСТВУЕТ, развёртывание обязано положить артефакт, иначе контур не исполняется вовсе, носитель — строка 251; сверка STACK.md 09.08 — факт шире прежней декларации «одна банкнота»); эскалация в shipping за budget_usd: 0 (STACK.md §примечания).
  • ЕДИНЫЙ БЭКЛОГ — отдельный файл BACKLOG.md (одна таблица, единственный трекер проекта, ID строк прежние; каждая петля обязана иметь диспозицию: решено / отложено-с-записью / отклонено; ведёт оркестратор). ⚠ Счёт очереди — бюллетень в ШАПКЕ ТОГО ФАЙЛА, здесь копии НЕТ (python3 docs/scripts/counts.py; переезд 06.09 — D39.218).
  • Архивы хроники: archive/PROGRESS-2026-07-04-10.md (D31) · -10-13 (D39.6-гигиена) · -13-25 (стройка паков 1116, rerun2) · -25-31 (паки 1720 · мини-прогон · полигон-пакеты 58 · ToS · холодный прогон; D39.2658) · -08-01-02 (сессии №9/№10: общность · качество банка · coldrun-b · открытие фронта/платформы; D39.5990, срез D39.105) · -08-02-04 (сессии №11№13: ручки эффорта · стандарты · контракт API · платформа P0 · банк-арбитраж; D39.91105 + снимок шапки эры №15) · -08-04-09 (пинги закрытых паков эры №15) · -08-14-15 (закрытые бэкенд-записи №1617: эмиттер шва · migrate · пере-пин DeepSeek; вынесено D39.139). Записи ниже — живой хвост (№16+, эра D39.124+; подрезка D39.139).

📌 СОСТОЯНИЕ ПАКОВ

Залендены и ратифицированы, приёмочные дампы — телами нот: платформенный P11 — D39.169 · движковый пак «деньги» — D39.170 · платформенный P12 — D39.180 (вместе с контрактным минором 0.9.0; PD-425 закрыт им же) · бэкенд-пак «деньги и честность выдачи» — D39.182 (тестов 1045→1083, удалённых ноль) · закон раскрытия движка — D39.181, ратифицирован владельцем и применён к одиннадцати экземплярам.

ПАКИ 05.09 ОТРАБОТАНЫ И ПРИНЯТЫ ОБА С ДОФИКСОМ, промты в archive/prompts/ с баннерами исхода, зоны свободны: движковый «денежный стоп» — 81a89e9 + 616a8e4, акт D39.206 (18 находок приёмки, 6 снято, 12 устояло, 4 major — все четыре оказались УТВЕРЖДЕНИЯМИ, а не поведением); платформенный «пустить внутрь можно» — 7e2226a + 3e84716, акт D39.201 (20 находок, 5 снято, 15 устояло, 5 major — ТРИ в самом механизме бэкапа). Ниже — история паков 04.09. ПАКИ 04.09 ОТРАБОТАНЫ И ПРИНЯТЫ ОБА (испр. 05.09). Платформенный «закрыть цикл» — adf5e53, D39.194, контрактный минор 0.10.0 тем же актом (⚠ эррата 04.09-в: минор ратифицирован БЕЗ своей кодовой половины и сутки жил ложным на проводе; починено 7e204db). Движковый вайр-батч — приёмочный коммит 74ffe4f, D39.199, принят С ДОФИКСОМ; строки заказа 210·113·46·134·140·184·232 ЗАКРЫТЫ и сняты из таблицы, найденное вне карты отчёта заведено строками 287290. ⚠ Эррата 04.09-д («пак НЕ принят») ИСЧЕРПАНА этим актом. ПАКИ 05.09 ВЫДАНЫ И ИДУТ: движковый «денежный стоп перестаёт быть аварией» (archive/prompts/BACKEND_MONEYSTOP_SESSION_PROMPT_2026-09-05.md — строки 271 · 277 · 278 · защёлка отказа) и платформенный «пустить внутрь можно» (archive/prompts/PLATFORM_OPERATIONS_SESSION_PROMPT_2026-09-05.md — строки 269 бэкапы с предъявленным восстановлением · 270 дверь для не-браузерного клиента · 274 updateBook · рантбук деплоя). ПАКИ 04.09 РАБОТАЛИ ПАРАЛЛЕЛЬНО (зоны независимы по коду; сцеплений ДВА, и второе найдено 04.09 уже после выдачи промтов — оба про то, чтобы не сорвать платный прогон платформы:

(1) форма манифеста ЗАМОРОЖЕНА на окно (D39.190 п.5): гейт интейка — строгое равенство одной константе, бамп отправил бы каждую книгу в parser_unavailable. (2) ⚠ ДАННЫЕ ЯЗЫКОВОГО ПАКЕТА — ТОЖЕ. Правка backend/internal/lang/data/*.txt двигает EmbeddedVersioncutTag (докстринг backend/internal/pipeline/manifest.go: «the embedded data feeds the CJK numerals and sentence terminators that place boundaries») → ключ валидности манифеста → на платформе recut := storedKey != in.ManifestKey (platform/internal/pgstore/readmodel.go) → delete from unit_resolutions where book_id. То есть у книги, за которую заплачено, исчезают замечания читателя и счётчики глав — это строка бэклога 198. ⇒ Лендинг правки данных не кладётся, пока книга платного прогона живая; порядок лендинга — обязанность оркестратора, зоны об этом предупреждены пингами 04.09. Рычаг у бэкенда есть и он объявлен предпочтительным: снять рендер в Go, данные не трогать): бэкенд — вайр-батч docs/BACKEND_WIREBATCH_SESSION_PROMPT.md; платформа — «закрыть цикл» docs/PLATFORM_EXPORT_SESSION_PROMPT.md. ⚠ Строка 160 взята, но идёт СВОИМ паком ПОСЛЕ двери: она бампает manifestVersion, у которого безопасного порядка деплоя нет (D39.190 п.2). Строка 142 — после шагов 01 полигона (D39.190 п.3). Предыдущие паки ОТРАБОТАНЫ 03.09, ПРИНЯТЫ С ДОФИКСОМ и залендженыD39.187 движок, D39.188 платформа; составы и приёмочные дампы ТЕЛАМИ НОТ, промты в archive/prompts/ с баннерами исхода, план паков — archive/reports/NEXT_PACKS_PLAN_2026-09-03.md, решения — D39.190. ⚠ Живое отсюда одно и оно уже вылечено паком P13: у формы манифеста БЕЗОПАСНОГО ПОРЯДКА ДЕПЛОЯ НЕТ — гейт интейка сравнивает версию со строгим равенством одной константе (platform/internal/ingest/manifest.go, греп KnownManifestVersion), окна двух версий нет, поэтому порядок «сначала платформа, потом движок» из рантбука разворачивается на обратный.

СНЯТО ЛЕНДИНГОМ 06.09 (D39.208): гейта БОЛЬШЕ НЕТ. Флаг едет в argv на КАЖДОМ спавне и пересчитывается, а названное ниже «живое основание» вылечено расширением условия — --resnapshot теперь едет на ЛЮБОМ продолжении, не только после правки банка (PD-422). Ниже — прежняя редакция, историей: Проводка --max-units в платформу остаётся ГЕЙЧЕНОЙ. Живое основание одно и оно механическое: единственный писатель bank_moved_at — дверь правок банка (platform/internal/runs/bank.go:211=one statement sets it), а рост АВТО-банка от майнинга этого флага не ставит, поэтому майнящая книга на второй покупке идёт без --resnapshot и умирает на снапшот-гарде движка — холд взят, попытка сожжена (PD-422). ⚠ Сюда же переехал остаток закрытой строки 234 (испр. 05.09): проводка полей rebill_* через шов — часть ЭТОГО гейта, а не отдельная работа; ревизия справедливо заметила, что после закрытия 234 её остаток остался без видимого носителя. Это чинится проводкой признака движения банка от майнинга, а не решением владельца.

ОТКРЫТО НА ОРКЕСТРАТОРЕ №22: Ресёрч-сессия textmachine-36 — лендинг research/29 ЗАКРЫТО 04.09. Оба отчёта топологии заленджены полигоном на СВОЕЙ ветке по прямому указанию владельца (a7951a7) и приехали в main мержем ветки — то есть маршрутом, который и был назван правильным. Файлы на месте: docs/research/29-harness-topology-survey.md и …-codex.md.

ЖИВОЙ ОСТАТОК — РЕВЬЮ-ШАПКИ, и он на оркестраторе. У research/30 шапка НАПИСАНА 05.09 — долг по нему закрыт (попутно исполнена эррата, которую он сам требовал пять недель: research/22 «LinguaGacha явно НЕ в мульти-агент/редактор» помечено протухшим; и снято его же требование к 29-codex — якорь :368 протух, реальный носитель :108 говорит слабее и о другом). У 29-codex шапка НАПИСАНА 05.09 — и она подтвердила снятое выше независимо: его же §4 п.12 говорит, что пробел в long-form детекторе машинности — в held-out точности и доле ложных срабатываний, а не в русском языке. У research/29 шапка НАПИСАНА 05.09 — ДОЛГ ЗАКРЫТ ПО ВСЕМ ТРЁМ ОТЧЁТАМ. Первым в ней стоит §5.6: сфабрикованный sha256 (совпали 52 знака из 64, хвост дописан по памяти, потому что хеш ни разу не был виден целиком из-за cut в конвейере) — и норма, из него следующая: идентификатор, не виденный ЦЕЛИКОМ в выводе команды, нельзя воспроизводить по памяти. Тот же класс, что D39.207 п.5, пришедший с другой стороны. ⚠ И граница, которую обязан знать всякий, кто цитирует оттуда числа: из 113 находок автор лично пере-открыла ШЕСТЬ. ⚠ Расхождения 29 и 29-codex между собой НЕ разрешены никем — автор 29 не читала параллельный отчёт дальше его §1, (⚠ испр. 05.09: сама шапка 29 уже поправлена — «НЕ закоммичено» помечено протухшим, файл в main с a7951a7; здесь остаётся долг ШАПКИ, а не факта о коммите). До шапок читать оба отчёта как ФАКТУРУ, не как ратифицированное. ⚠ Формулировка, которую шапка обязана нести, иначе следующая сессия выбросит замеры топологии: судья как СТАДИЯ ДВИЖКА не построен и не вызывался (0 вызовов), но судьи в ПОЛИГОНЕ были и есть. Маршрут закрыт словом владельца 02.09: «не трогай соседнюю git tree ветку вообще» — файл принадлежит ветке polygon, в main приезжает мержем ветки, копированием из соседнего worktree — никогда (№22 так сделал, был поправлен, лендинг откачен).

НОРМЫ, ЗАРАБОТАННЫЕ ЭТИМИ ПРИЁМКАМИ:

  • Зелёная батарея — это ПОЛНЫЙ список пакетов ПЛЮС отсутствие FAIL, а не отсутствие FAIL: обёртка подавала exit 0 при падении в хвосте (поймала сама движковая сессия).
  • Линтер якорей гоняется ПОСЛЕДНИМ шагом, после того как код замер. Он судит доки трёх зон, но зоны его не зовут; в этот заход нашёл 21 указатель на исчезнувший код, и правки сдвигали цели дважды подряд — включая мои собственные, уже после починки.
  • Якорь разрешается тем, ЧТО он утверждает, а не номером строки, на которой лежал (движковая сессия записала переезд по совпавшему номеру и промахнулась предметом).
  • Колонка «подтверждено» отчёта, пойманного на ложных подтверждениях, снимается с доверия ЦЕЛИКОМ — критерий, отличавший ошибочные строки от верных, назвать нельзя.
  • pkill по имени процесса на машине с параллельными сессиями бьёт по чужим.
  • Число или «доказано» уходит владельцу только после СВОЕГО прогона.

⚠ ПИНГ ЗОНЕ БЭКЕНДА (оркестратор №22, 04.09, вечер) — РЕВИЗИЯ ДОКУМЕНТАЦИИ ЗОНЫ ЦЕЛИКОМ

Внешний ревизор прочитал backend/README.md, все 11 файлов backend/docs/ (включая оба PUML текстом) и арх-доки движка от первой строки до последней. Правит ЗОНА. Порядок — по цене ошибки.

1. README.md:36 описывает инвариант через ключи, которые загрузка ОТВЕРГАЕТ. «Канал adult — только permissive (fail-closed)»: permissive: и channel: — RETIRED и валят конфиг (internal/config/models.go, греп LegacyPermissive; internal/config/pipeline.go, греп LegacyChannel). Настоящий механизм — content_labels книги × accepts_labels модели — в README не назван ВООБЩЕ. Сессия, строящая маршрутизацию контента по README, получит неподнимающийся конфиг. Ту же ложь несут оба PUML.

2. ОБА PUML БЕЗ ⚠-БАННЕРА рисуют снесённое, при том что docs/README.md подаёт их как канонические диаграммы, правящиеся «одним коммитом с кодом»: exit-контракт из ЧЕТЫРЁХ кодов (в cmd/tmctl/main.go — коды 4, 5 и полоса 1019), глаголов 6 против 11, mined_delta/mined_rejects как ключи book.yaml (RETIRED, валят загрузку), машинная .bank-stop.json (снесена D39.158), Adult bool. В заголовке обоих — «синхронизировано с D1D39.25» при живой голове D39.195.

3. README.md:95 называет боевой редакторский промпт v3 (⚠ испр. 05.09: второй адрес этого пинга — 10-prompt-architecture.md:23 — снят, потому что этот файл ЗОНА ОРКЕСТРАТОРА и бэкенд его не правит; поправлено своей рукой) — в configs/pipeline-c1.yaml метка v4-discourse-reflow-nogenre, и с D39.182 она НЕСУЩАЯ (TestPromptLabelsPinTheirBytes). Поверивший README либо бампнет v3→v4 в уже-v4 файле, либо получит красный гейт.

4. README.md:3 обещает автоматику, которой нет: «подсистемы не импортируют друг друга (проверяется go list -deps)». Сама изоляция ДЕРЖИТСЯ — проверено, — но проверки нет: grep -rn 'go list' backend --include=*_test.go --include=Makefile → 0, а internal/archguard несёт три анализатора, границы импортов среди них нет. 13-tech-debt-anchors.md это констатирует, README нет.

5. ⚠ ОБЩНОСТЬ ПЕРЕОЦЕНЕНА, и долг без носителя. README.md:23 («гейты по данным, Go-веток по паре нет») и README.md:16internal/text — script-agnostic, без языковой политики») — сверх-утверждения: internal/text/norm.go встраивает китайскую таблицу трад→упр, складывает катакану в хирагану и БЕЗУСЛОВНО сливает ё→е для ЛЮБОЙ цели (белорусская цель ломается тихо); санитайзер считает только latinLetters/cyrLetters, поэтому греческая/арабская/хинди цель получает «латинскую вставку» на каждом слове; граница слова в банке проверяется только для Latin/Cyrillic. ⇒ Ревью-вопрос «пара, которой в репо нет, без правки Go» для не-кириллической цели отвечается НЕТ, а README это скрывает.

6. Ратифицированная норма зоны держится на СНЯТОЙ строке. DISCLOSURE_LAW_DESIGN.md:219-221: «Пока строка бэклога 246 открыта, новый класс вводится в полосу ТОЛЬКО вместе со сверкой… Закроется 246 — оговорка снимается». 246 ЗАКРЫТА 04.09 (D39.194) ⇒ оговорка снялась молча, и это надо подтвердить или переписать сознательно, а не по факту исчезновения строки.

7. ⚠ СЕМЬ ПРОТУХШИХ ТОКЕН-ЯКОРЕЙ В backend/docs/ — и до сегодня их не видел никто. Корень backend/docs в линтере ОТСУТСТВОВАЛ с самого его заведения; добавлен 04.09 (docs/scripts/counts.py, греп backend/docs в lint_anchors). ЗАКРЫТО 05.09: все семь пере-навешены (616a8e4 два мёртвых + e7d6b3f пять съехавших), --lint → 0. Ниже — состояние на середине дня, читать как историю. ⚠ Прежняя редакция: «починены ДВА из семи, пять живы» (DISCLOSURE_LAW_DESIGN.md:40-44 целят в quality.go · status.go ×3 · bookbuild.go — зона бэкенда, пинг в её секции). ⚠ Прежняя редакция этой строки говорила «семь пере-навешены» — ложь, выведенная из ожидания, а не из прогона линта; поймана внешним ревьюером. Починенные два не съехали, а УМЕРЛИ: целили в (DISCLOSURE_LAW_DESIGN.md:264 и MONEY_HONESTY_REPORT.md:285) не съехали, а УМЕРЛИ: целили в chunkrun.go=SourceEchoExpected: role == roleTerminologist, подстроки которой на HEAD нет вовсе — её съел переход на isBankRole. Прежняя редакция этой строки перечисляла краснеющие цели и была верна ровно до починки. Прежде краснели: DISCLOSURE_LAW_DESIGN.md:40-44 (пять целей подряд — quality.go, status.go ×3, bookbuild.go), :264 и MONEY_HONESTY_REPORT.md:285 (chunkrun.go:40). ⚠ Эррата D15.2 от 02.09 УЖЕ указывала мимо — гейт не мог этого увидеть по построению. Команда: python3 docs/scripts/counts.py --lint.

8. Ссылки «строка N» на строки, ВЫПАВШИЕ из таблицы при закрытии: README.md:26 (103 — фантом, снят 31.08), pipeline.puml (99 · 100 · 101 · 125 · 145), DISCLOSURE_LAW_DESIGN (246 · 238 · 239 · 194), internal/membank/decisions.go:84 (210 — закрыта 04.09). Бэклог закрытые строки НЕ хранит, а доки зоны адресуют их как живые.

9. Мелочи с адресом: README.md:5 «актуализировано 01.08», тело цитирует ноты 2328.08 · 13-tech-debt-anchors.md:174 цитирует STACK.md в состоянии, которого там уже нет (ручка эффорта proоба носителя датированы 04.09 и противоречат) · SEAM_PACK_FINDINGS.md:130 «у bank-apply ноль вызывающих на платформе» — platform/internal/runner/bankapply.go строит вызов · :1133 «два хита» → четыре · MONEY_HONESTY_PLAN-NOTE.md:35 «22 поля» → 21 на её же HEAD.

10. НЕ ОПИСАНО, А НАДО: пакет internal/langscreen (новый, на денежном пути вердиктов) в README не упомянут вовсе · карта пакетов не называет ~20 несущих файлов internal/pipeline (volume.go, rebill.go, reprice.go, refusal.go, terminologist.go, bookbuild.go…) и пять в internal/store · cmd/tmmutate (каталог посадок, объявленный ГЕЙТОМ; ⚠ число из этой строки снято 06.09 — стояло «141», в дереве 211: литерал в рабочей строке живёт дольше предмета, поэтому здесь его больше нет — счёт берётся из cmd/tmmutate/mutations.json) и cmd/tmvet не названы · цена закона раскрытия («загейчен на 40 %», Г1/Г2 не построены) в статус-борде 09 не оговорена.

Что оркестратор поправил СВОЕЙ рукой в свою зону тем же заходом: статус-борд 09-target-architecture.md говорил «цикл РАЗОМКНУТ» и «канон 0.9.0» в день своего же «освежения» — оба ложны с adf5e53/58bca19; висячая ссылка на закрытую 246 в шапке секции «Бэкенд»; корень backend/docs в линтере.

Бэклог

ПЕРЕЕХАЛ 06.09 в BACKLOG.md (ратификация — D39.218). Таблица вынесена дословно, номера строк не менялись: «строка N» ищется там же, чем и здесь — grep -n '^| N |' docs/BACKLOG.md. Заголовок оставлен НАМЕРЕННО, чтобы прежние ссылки «секция „Бэклог“ в PROGRESS» доезжали в один хоп. Счёт очереди — бюллетенем в шапке того файла; здесь копии НЕТ (один носитель на факт, D39.112).

(Указатели на архив-слайсы хроники — бюллетенем «Архивы хроники» в CURRENT-STATE; здесь копий нет.)

Бэкенд

Пак «ЗАКОН БАНКА — ЧЕСТНО» (06.09, промт docs/BACKEND_CONSISTENCY_SESSION_PROMPT.md, вход HEAD e4097cb). НЕ КОММИЧУ — ждёт лендинга

Итог: закон банка описан тем, что код делает, и найдена дыра ШИРЕ заказанной — стадия схлопывания не сверяла свою выработку со строкой банка на тот же ключ ни при какой подписи. Закрыто в двух местах (схлопывание + страховка на слиянии), репортом, без смены поведения платного прогона. ШЕСТЬ кругов самопроверки нашли 43 находки В МОЕЙ ЖЕ работе (18 + 8 + 5 + 6 + 4 + 2); круг 6 сказал «сошлись» — новых находок в коде пака нет. Шесть находок — ложные утверждения в моих же комментариях, то есть ровно тот класс, который пак чинил; две внесены лечением предыдущего круга; один и тот же шов «писатель ↔ читатель» ловился ТРИ круга подряд, после чего был убран целиком, а не подпёрт четвёртой заплатой. Все разобраны, списки ниже.

Комментарии этой смены написаны под рекомендацию владельца 06.09 («только важные детали или обоснования, без прозы, воды, истории и странных гарантий»; носитель — docs/architecture/12-go-style-notes.md §1, статус РЕКОМЕНДАЦИЯ). Применена только к СВОИМ комментариям пака: сплошного приведения корпуса рекомендация не заказывает. Единственный комментарий вне пака, который я тронула, — internal/pipeline/export.go (TextModified): моя правка chunkstatus.go сделала бы его утверждение рассогласованным, и оставить два живых противоречащих описания одного факта было нельзя. ⚠ Второй круг самопроверки исполнен ДОБРОВОЛЬНО: владельцем эта половина не подтверждена, каноном не стала, и как на решение владельца я на неё не ссылаюсь.

0. Исход по КАЖДОМУ пункту заказа — пунктов без исхода нет

пункт промта исход чем предъявлено
§4.1(а) пере-снять замер сделано таблица §1 ниже, каждый ноль с контролем
§4.1(б) закрыть непокрытое сделано в двух местах membank.ConsolidationKeyConflicts + расширенная UnverifiedKeyConflicts; пины + 18 мутаций
§4.1(в) «варнинг → стоп» сознательно не делаю — по промту это пинг; вынесено оркестратору, он развёл «видеть» и «делать» по уровням и завёл строку бэклога в коде ни return err, ни drop: обе проверки только WarnContext
§4.2 совет про статус сделано, вариант 1 (текст приведён к коду); вариант 2 отвергнут по существу — вернул бы развилку по статусу, закрытую D39.104 п.2 замер «status: auto не растворяет ливлок»: инжектятся ОБЕ (2/2/2), контроль 0; пин + 2 мутации
§4.3 комментарий постчека + пин сделано, плюс два носителя той же лжи вне промта TestWrongDstObeyedIsNotAMiss + мутация
§4.3 детектор ЗНАЧЕНИЯ сознательно не делаю — запрещён промтом, живёт строкой 286 в диффе нет source-side проверки
§4.4 sticky в редакторской волне сделано (комментарий); сам перенос НЕ строю — по строке 321 сначала замер дрейфа waverun.go, nil на месте; оба механизма названы с file:line
§4.4 резюм и строка статуса сделано — поведение установлено по коду и запинено TestOrdinaryResumeMovesOnlyTheSkippedRow + 2 мутации; мнение автора промта проверено, а не унаследовано
§4.5 строки 322 / 295 / 161 / 283 не делаю — прямо исключены промтом в диффе их нет
§5а список сделано, 9 позиций с file:line; ни одна не чинилась секция §8
П1 страховка на слиянии сделано варнингом формат сообщения + 4 мутации; корпусный замер
П2 только репорт соблюдено отказ не построен
П3 маркер на листе подписи сделано, маркер отличен от Contradicts пин + 2 мутации; предъявлено, что сдвинулся только сайдкар

1. Пере-снятый замер §4.1(а): постановка подтвердилась и оказалась уже правды

$0, мои руки, выброшенные пробы. Каждый ноль с контролем. Точка слияния, windowsOverlap([0,0],[3,9])=true (контроль [0,2]×[3,9]=false):

популяция ApprovedSharedKeyCollisions UnverifiedKeyConflicts
approved × approved (КОНТРОЛЬ) 1 0
approved × auto (КОНТРОЛЬ) 0 1
draft×auto, draft×draft, auto×auto 0 0
общий alias, draft × auto 0 0
общий alias, approved × approved (КОНТРОЛЬ) 1 0

Внутрифайловый parseBankSeed: тот же Src, draft×auto, один файл → REFUSED (статус-слеп); общий alias, draft×auto → LOADED, ни один гард не сработал.

Поправка к строке 267, принята оркестратором: контроль «общий alias, approved×approved, один файл» тоже LOADED — LoadGlossarySeed alias'ы не сравнивает вообще. Непокрытие через alias внутри файла — не только для неподписанных; для подписанных страховка стоит этажом выше (bankmaterialize.go:142).

2. Главная находка (в промте и строке 267 её нет)

Стадия схлопывания не сверяет выработку с существующей строкой банка на тот же firing-ключ — ни при какой подписи. Слово владельца в строке 267 указывает сюда, и оно шире исходной постановки. Предъявлено пробами:

  • CanonConflicts при кандидате 元始→«камень первоисточника» и ПОДПИСАННОЙ 元始→«юаньшивернула 1 конфликт, но **не этот**: назвала составное元始空窍. Прямая пара пропущена по построению (terminology.go:941пропускаетn.Src == c.Key; CanonFor:873` — «a candidate that IS the signed row has nothing to learn from it»). КОНТРОЛЬ на случае, ради которого проверка строилась → 1.
  • ConsolidationConflicts на «та же поверхность дважды» → 0; КОНТРОЛЬ «составное роняет свою же часть» → 1.
  • Ветка не мёртвая: unsignedEngineSurfaces выкидывает неподписанную mined-строку из сид-поверхностей майнера (выжила 1 из 2, именно approved), а terminology.Merge(nil, 2 observed) кладёт в кандидаты обе поверхности, включая ту, что банк держит approved (КОНТРОЛЬ: Merge(nil,nil)0). Фильтр сид-поверхностей стоит на ЭМИССИИ (mining.go:549), не на входе в роль.

3. Что построено

(а) membank.ConsolidationKeyConflicts — сверка каждой схлопнутой формы с любой строкой банка на общий firing-ключ (src или alias) при перекрытии окон и другом dst, независимо от статуса обеих сторон. Возвращает []BankKeyConflict (части, не предложения: рендерят две поверхности — лог и лист подписи). Пара с совпадающим UNIQUE-кортежем не репортится: схема не даёт обеим строкам существовать. Сравнение кортежа идёт по СЫРОМУ Src, потому что таков ключ хранилища (см. §4-бис п.1: 族長 и 族长 с одним окном — две законные строки); соответствие обеспечивает вызывающий, передавая источник, который строка получит при посадке. ⚠ Проверка сформулирована как РАЗНОГЛАСИЕ, а не как предсказание «обе формы поедут на провод». Так вышло по находке второго круга: для сид-поверхности эмиссия роняет предложение, а авто-банк переписывается целиком, поэтому «BOTH survive» было бы ложью ровно на сценарии, который пиннит мой же тест. Три механизма разрешения названы в доке. Проводка — terminologist.go: glossaryRows() (одно чтение банка, столько же обращений к store, сколько было), consolidatedRows(), terminologyResult.BankConflicts + BankHolds.

(б) membank.UnverifiedKeyConflicts расширена (П1): было «approved × неподписанная», стало «любая пара, кроме approved×approved» (та у fail-loud). Осталась ВАРНИНГОМ по прежнему доводу. Нужна отдельно от (а): состояние достижимо и без схлопывания — рукописный сид draft + рукописная дельта draft с разными окнами при выключенном гейте терминолога. Сообщение называет обе строки, их подписи, оба окна и firing-ключ (statusLabel, windowLabel[ch 3..9]/[ch 1..end] вместо сырых нулей, которые читались бы как пустое окно).

(в) Находка доезжает до листа подписи (П3): BankStopRow.BankHolds + маркер THE BANK ALREADY HOLDS: — отдельное поле и отдельный маркер от Contradicts/CONTRADICTS this run's own.

(г) §4.3 — комментарий постчека приведён к поведению + пин TestWrongDstObeyedIsNotAMiss. Промах = форма ОТСУТСТВУЕТ, и только это; послушанный неверный dst присутствует, if present { continue } берётся, промаха нет. Ноль confirmed-промахов говорит про ИСПОЛНЕНИЕ ПОДПИСАННОЙ половины банка — про неподписанную не говорит ничего (её промахи уходят в Unverified и не считаются). Те же ложные утверждения найдены грепом и сняты ещё в двух местах, которых в промте не было: pipeline/disposition.go:90 и cmd/tmctl/render.go:366.

(д) §4.2 — совет «or mark one status: auto» снят. Установлено исполнением: при status: auto на второй строке инжектятся ОБЕ (approved→2, draft→2, auto→2; КОНТРОЛЬ «src отсутствует в чанке» → 0). Под D39.104 п.2 провод не ветвится по статусу ⇒ статус-слепота гварда ВЕРНА, а совет — осколок до-D39.104 эпохи. Выход №2 («научить гвард смотреть статус») отвергнут по существу: он вернул бы закрытую доктриной развилку.

(е) §4.4 — два ложных комментария сняты. waverun.go: оправдание nil-переноса sticky заменено фактом — assignEditUnits закрывает единицу внутри главы, sticky сбрасывается на границе ГЛАВЫ, 1962 из 2283 глав многоединичны (замер строки 321, не мой, атрибутирован); перенос НЕ строю. chunkstatus.go: см. §5, там моя формулировка была неверна дважды.

(ж) Попутно исправлена собственная ложь, созданная расширением: seeding.go:73 говорил «an UNSIGNED row contradicts an APPROVED term» — неправда для новой половины. Текст приведён к правилу. Прежняя приписка «на старый текст не стоял ни один тест (grep = 0)» ОПРОВЕРГНУТА приёмкой и снята — и это мой собственный «прибор ответил на свой вопрос». Я грепала ЦЕЛУЮ фразу, которая живёт только в самом seeding.go, поэтому ноль был предрешён. Правда обратная: сообщение БЫЛО запинено ПОДСТРОКОЙ (pipeline.TestUnsignedConflictIsReportedByTheRun утверждал "contradicts an approved term"), батарея от расширения ПОКРАСНЕЛА, и правку этого самого теста объявляет §9 п.2 того же отчёта. То есть отчёт противоречил сам себе через две секции.

4. Что нашли ДВА круга самопроверки в моей же работе

Круг 1 — интервальный контролёр по явным критериям + опровергатель (оба Fable, оба на копии дерева). 18 находок, все разобраны. Самые дорогие:

  1. chunkstatus.go — моя правка §4.4 была ЛОЖНОЙ. Я написал «обычный резюм ничего здесь не пишет». Оба агента предъявили обратное, и я воспроизвёл сам: $0-резюм (провайдер-вызовов 3→3) сдвинул updated_at СКИПНУТОЙ строки (ch1/chunk0/edit: 19:48:13 → 19:48:14) при неподвижных ok и flagged (КОНТРОЛЬ: 3 строки из 4 не двинулись). Механизм: скип — не хранимый вердикт, флагнутая строка отдаётся из чекпойнта, а runStageSequence (waverun.go) пере-апсертит скип каждым прогоном. ⚠ Моя ПЕРВАЯ попытка назвать механизм тоже была неверна (указала на fast-path stagerun.go); поймано мутацией — мутант «fast-path обслуживает скипнутые» ПЕРЕЖИЛ пин. Формулировка исправлена на waverun.go, близнец export.go (TextModified) приведён в согласие, поставлен пин TestOrdinaryResumeMovesOnlyTheSkippedRow.
  2. Ложное срабатывание, класс A: для сид-поверхности, задетой через banknote, выработка НИКОГДА не ложится (эмиссия её роняет), поэтому мой текст «the term would carry TWO renderings» был ложью ровно на сценарии моего же теста. Проверка пере-сформулирована как разногласие; текст варнинга и док переписаны.
  3. Ложное срабатывание, класс B: сравнение UNIQUE-кортежа шло по сырым Src, а banknote-кандидат несёт сырую поверхность против нормализованного ключа ложащейся строки (族長 против 族长). ⚠ Лечение круга 1 было неверным (свёртка обеих сторон) и переделано на круге 2 — см. §4-бис п.1.
  4. Мой собственный комментарий повторял чужой misnomer: «dropped where a SIGNED row holds the key» — loadAutoBank роняет предложение по ЛЮБОЙ ранее собранной строке любого статуса. Исправлено и названо ценой пропуска.
  5. consolidatedRows не пиннился ничем: мутации «убрать SinceCh» и «убрать алиасы» переживали весь пакет pipeline. Добавлен TestConsolidatedRowsCarryTheWindowAndTheAliases; обе мутации теперь ловятся с верным текстом.
  6. Три дефекта в моём корпусном приборе: классификация пары по подстроке : approved " ловила только случай, когда approved-строка печатается первой; booksSeen был тождествен booksWithRows по построению (мёртвая «контрольная» величина); подсадка строилась от g[0], у которой может не быть огневого ключа или dst ⇒ ложный ОТКАЗ прибора. Все три закрыты, числа после починки те же.
  7. Двойной репорт в ОДНОМ прогоне — подтверждён моим прогоном на ДЕЛЬТА-фикстуре (test-book.mined-delta.yaml с неподписанной строкой 方源→Странник): авто-режим после writeAutoBank пере-сидит, и UnverifiedKeyConflicts называет ту же пару через 2 мс после стадии схлопывания — collapse=1, merge=1, КОНТРОЛЬ всего 3 строки WARN. ⚠ Фикстура названа по находке круга 5: на СИД-фикстуре моего же e2e выходит collapse=1, merge=0, потому что эмиссия роняет предложение по сид-поверхности, и без имени фикстуры число читалось бы как общее. НЕ подавлял: это разные состояния одного термина («роль расходится с банком» до того, как строка легла, и «банк держит обе» после), и только второе означает две строки на проводе. Названо в доке; если оркестратор сочтёт это шумом — резать надо слияние.
  8. Линтер нашёл два настоящих дефекта в приборе: непроверенный rows.Err() в обоих запросах. Для измерительного прибора это ровно та неисправность, ради которой он написан: усечённая итерация вернула бы меньший банк как чистый. Разведено на две функции с defer rows.Close() и возвратом rows.Err().

Мелкие, тоже закрыты: перебор в «zero says the bank was EXECUTED»; render.go — строка detail несёт и ambiguous-промахи, поэтому «an approved rendering» верно для гейта, не для строки; ассерт «one fault, not two: []» давал верный вердикт при нуле с неверным текстом.

4-бис. КРУГ 2 самопроверки — восемь находок, три серьёзные, все в моей же работе

Мандат круга 2 (добровольный, см. оговорку выше): проверить ИСПОЛНЕНИЕМ и исходный заказ, и закрытие находок круга 1. Проверяющий — отдельный агент на копии дерева, 19 мутаций, каждая восстановлена со сверкой sha256.

  1. МОЙ ФИКС НОРМАЛИЗАЦИИ БЫЛ НЕВЕРЕН, А ДОВОД ПОД НИМ — ЛОЖЕН. По находке круга 1 я свернула сравнение UNIQUE-кортежа через NormalizeSourceKey и написала «схема не даёт обеим строкам существовать». Пере-мерила сама: ReplaceGlossary(族長 + 族长, один sense и окно)err=nil, rows stored=2; КОНТРОЛЬ с байт-равным srcUNIQUE constraint failed: glossary.book_id, glossary.src, glossary.sense, glossary.since_ch, glossary.until_ch. UNIQUE стоит на СЫРОМ src, и трад/упрощённая пара — две законные строки, обе из которых инжектятся. Значит моя свёртка вводила ЛОЖНООТРИЦАНИЕ: пропускала настоящее противоречие. Вылечено по-настоящему, а не заплатой: сравнение вернулось к сырому (зеркалит ключ хранилища), а consolidatedRows строит строку с Src: c.Key — тем источником, который она РЕАЛЬНО получит при посадке (mining.go кладёт Src: c.Key). Обе половины запинены (TestConsolidationTupleSkipMirrorsTheStoreKey, усиленный TestConsolidatedRowsCarryTheWindowAndTheAliases), обе мутации красны с верным текстом. ⚠ До круга 2 мутация «свернуть сравнение» ПЕРЕЖИВАЛА весь пакет — фикс был не запинен вовсе.
  2. chunkstatus.go — не тот механизм В ТРЕТИЙ РАЗ подряд. Скип в шипящей раскладке (редакторская волна, единица с флагнутым черновиком) пишет recordSkippedStages, а не флагнутая ветка runStageSequence: та берётся только при ≥2 стадиях в ОДНОЙ волне. Поймано мутацией — правка ветки runStageSequence мой пин ПЕРЕЖИЛА, а правка recordSkippedStages его уронила с верным текстом. Названы оба писателя, в доке пина тоже.
  3. Пропуск по кортежу молчит на самой частой форме сид-строки (окно по умолчанию, без sense). Замер: та же фикстура без until_ch: 20BankConflicts=0 и при draft, и при approved; с until_ch: 20 → 1. Мой же e2e-тест обходил это подобранным окном, и я этого не вынесла. На провод не влияет (предложение отбрасывается), теряется строка на листе подписи. Названо ценой в доке ConsolidationKeyConflicts и вынесено в §5а №7.
  4. Тихий ноль, внесённый ЭТИМ паком: glossaryRows возвращал nil при ошибке чтения банка без единого слова, из-за чего BankConflicts=0 неотличим от «конфликтов нет». Теперь логируется явно, с формулировкой «их нули означают „не спросили“, а не „не нашли“».
  5. Перебор в §4.3: «ноль confirmed-промахов = подписанная половина исполнена» — неточно: Confirmed требует и approved, и ДОВЕРЕННОГО ключа, а промах на одно-Han ключе демотируется в Unverified. Приведено к «подписанные строки, сработавшие на доверенном ключе».
  6. Стиль (правило владельца): довод «containment + equal-source + approved-only» стоял ТРИЖДЫ — оставлен там, где живёт проверка, остальные заменены ссылкой; снята история в тесте («эта фикстура всегда несла»), план в коде («carry stays unbuilt until it is»), чужой замер 1962/2283 атрибутирован стенд-книге и дополнен file:line обоих механизмов. Проверяющий отдельно искал ПОТЕРЮ нужной детали при сокращении и не нашёл (перечитаны все 14 файлов диффа).
  7. §5а вырос с 6 позиций до 9: №6 bankmaterialize.go:127 (та же ложь про «signed»), №7 пропуск по кортежу на форме сид-строки по умолчанию, №9 — путь записи статуса не читается по коду (писателей два, выбор решает раскладка волны). Тихий ноль glossaryRows не вынесен, а ЗАКРЫТ.
  8. Подтверждено круга-2 замером: довод про двойной репорт верен по коду (mining.go:241-246); корпусный прибор после починки даёт те же числа и симметричную классификацию; обе мутации consolidatedRows ловятся; ассерт «0 против 2» различает случаи.

Итог по кругам: 18 находок в круге 1 + 8 в круге 2, из них ПЯТЬ — ложные утверждения в моих же комментариях. Это тот самый класс, который пак чинил, и он воспроизвёлся на мне пять раз. Единственное, что его ловило надёжно, — мутация, прочитанная ПО ТЕКСТУ: три раза пин переживал мутацию, и каждый раз это означало не дыру в пине, а неверный механизм в моём описании.

4-кватер. КРУГ 3 — РЕГРЕСС от моего же лечения круга 2, плюс четыре мелочи

Круг 3 подтвердил, что все шесть находок круга 2 закрыты, и нашёл одну новую — самую дорогую в паке, потому что её внесла МОЯ ПРАВКА:

  1. РЕГРЕСС: метка листа подписи терялась ровно у той популяции, ради которой правка делалась. Лечение круга 2 сменило ключ, которым terminologist.go пишет карту res.BankHolds (стал ключ посадки, cf.Src == c.Key), а mining.go продолжал читать её по c.Src — СЫРОЙ поверхности кандидата. У banknote-кандидата с Key != Src (традиционное написание, регистр, кана) метка THE BANK ALREADY HOLDS до листа не доезжала: счётчик и лог верны, требование П3 нарушено молча. Мои же пины этого не ловили: юнит-пин останавливался до bankStopRows, а e2e-пин стоит на 方源, где Key == Src. Вылечено переводом чтения на tres.BankHolds[c.Key] (так же, как рядом читается Conf), пин продлён через bankStopRows на кандидате {Key: 赵甲, Src: 趙甲}, мутация обратно на c.Src красна: «the mark must reach the sheet for a candidate whose key differs from its surface: {Src:趙甲 … BankHolds:[]}».
  2. Отчёт §3(а) описывал отменённую версию кода («сравнение свёрнуто через NormalizeSourceKey»). Приведён к коду; греп отозванной фразы → 0 при контроле 1.
  3. Нумерация §5а шла 1..7, 9, 8 — выправлена.
  4. Два абзаца доки ConsolidationKeyConflicts носили один заголовок «Cost of the skip» и читались как дубль, хотя это разные цены. Разведены: «WHAT THE SKIP HIDES» (форма сид-строки по умолчанию) и «WHO RESOLVES A SKIPPED PAIR» (loadAutoBank роняет по строке любого статуса).
  5. Варнинг glossaryRows обещал молчание обеих проверок, хотя из scoreOpts затрагивается только якорь скоринга, и при стойкой ошибке чтения печатается трижды за роль. Текст сужен до «whatever this call feeds», повторяемость названа.

Урок круга 3, который дороже самой находки: правка, сделанная ПО находке ревью, — такой же новый код, как всякий другой, и требует своего пина. Мой фикс круга 2 был верен по существу и сломал доставку на этаж выше, потому что я запинила изменённую функцию, а не путь до потребителя.

4-квинтус. КРУГ 4 — зеркало того же шва плюс асимметрия доставки

Круг 4 подтвердил все пять пунктов круга 3 закрытыми и нашёл четыре новых. Главная — того же класса, что регресс круга 3, но с другой стороны шва:

  1. Сторона ЗАПИСИ карты BankHolds не была запинена вовсе. Мутации ключа записи на cf.Key (firing-ключ, может быть АЛИАСОМ) и на cf.BankSrc (поверхность строки банка) переживали весь пакет pipeline. Причина названа точно: мой юнит-пин строил карту СВОЕЙ копией продакшн-цикла, а не звал продакшн-писателя, а e2e-пин стоит на 方源, где ключ кандидата, сырая поверхность, firing-ключ и поверхность строки банка — одна и та же строка, так что любой из четырёх ключей проходил. Вылечено выделением одного писателя bankHoldsByCandidate, которого зовут и продакшн, и пин; фикстура подобрана так, что все четыре строки различаются. Обе мутации красны с верным текстом.
  2. Стдаут-таблица стопа печатала ⚠ contradicts: и НЕ печатала маркер банка (cmd/tmctl/render.go) — оператор на первом экране видел одно разногласие и не видел второго, при том что пак сам обосновал их равенство. Добавлена строка ⚠ bank holds: рядом с братом.
  3. Абзац «WHO RESOLVES A SKIPPED PAIR» смешивал две популяции и утверждал «nothing reporting it». По коду: для СИД-поверхности резолвер — фильтр эмиссии (reverseSectionTerms), а не loadAutoBank; для ДЕЛЬТА-строки — loadAutoBank, и дроп ЛОГИРУЕТСЯ, но текстом «held by a signed term» при любом статусе держателя, то есть оператору говорят НЕВЕРНОЕ, а не ничего. Абзац разведён, §5а №1 отчёта приведён к этому же.
  4. Дока поля BankHolds говорила «per candidate src», а комментарий писателя — «keyed by the KEY»: два комментария к одному полю расходились ровно в том слове, на котором сломался круг 3. Сведены.

Плюс два числа отчёта не воспроизводились и были пере-сняты: счётчик ссылок на BankHolds устарел после продления пина, а контрольная формулировка «Contradicts дальше листа и лога не идёт» оказалась ложной — он печатается в стдаут, и именно эта находка привела к п.2.

Урок круга 4: тест, который ВОСПРОИЗВОДИТ продакшн-логику копией вместо вызова, пинит собственный цикл, а не код. Два круга подряд дыра сидела на одном шве «писатель ↔ читатель», и оба раза её прятала фикстура, где все кандидаты на ключ совпадают.

4-секстус. КРУГ 5 — сошлись по ПОВЕДЕНИЮ; остаток был в пинах и тексте, и шов убран целиком

Круг 5 подтвердил: регресса в лечении круга 4 нет, все пять пунктов закрыты и воспроизведены исполнением (включая замер, которого я не сделала сама на круге 1 — дроп дельта-строки действительно логируется словом «signed» при держателе status=draft). Остаточных находок четыре, все в пинах и тексте:

  1. Шов «писатель ↔ читатель» бил ТРИ круга подряд, поэтому убран, а не подпёрт четвёртой заплатой. Круг 5 показал, что даже после выделения общего писателя мутация «продакшн обходит писателя и вписывает свой ключ» переживает весь пакет: e2e стоит на 方源, где ключ кандидата, сырая поверхность, firing-ключ и поверхность строки банка — одна строка. Решение по D39.216: карты больше нет. terminologyResult.BankHoldRows несёт находки НЕГРУППИРОВАННЫМИ, сопоставляет их с рядом одна функция bankHoldLabels в том файле, который их потребляет, — то есть ключ выбирается в ОДНОМ месте, а не по разу с каждой стороны. Три мутации ключа сопоставления (cf.Key == c.Key, cf.Src == c.Src, cf.BankSrc == c.Key) теперь красны на одном пине с текстом про сломанное.
  2. Строка ⚠ bank holds: в стдауте была без пина — и её брат ⚠ contradicts: тоже. Добавлен TestRenderSignatureStopShowsBothDisagreements; обе мутации (удалить любой из двух блоков) красны, контроль — ряд без маркеров не печатает ни одного.
  3. Абзац доки обобщал дельту: до loadAutoBank доходит только НЕПОДПИСАННАЯ дельта-строка, потому что approved-дельта остаётся сид-поверхностью для эмиссии (unsignedEngineSurfaces). Уточнено одним словом.
  4. Корпусный прибор проходил на пустом обходе (TM_CORPUS=/nonexistent → PASS при walked=0 — ровно тот класс, ради которого он написан), и trimTo резал байты, а не руны, на ханьских и кириллических сообщениях. Оба закрыты: пустой обход теперь t.Fatalf, срез рун-безопасен.

Плюс пере-сняты шесть устаревших file:line отчёта (сдвинулись моими же правками) и названа фикстура у числа «collapse=1, merge=1»: оно ДЕЛЬТА-фикстуры, а на сид-фикстуре выходит 1 и 0, потому что эмиссия роняет предложение.

Урок круга 5, и он про архитектуру, а не про внимательность: если одна и та же дыра ловится три круга подряд в разных её точках, чинить надо не точку, а шов. Карта, ключ которой выбирается дважды, — это два места для одной мысли; после перестройки мест стало одно, и все три мутации ключа ловит один пин.

4-тер. Находки кругов → что сделано → чем предъявлено

находка (круг) что сделано чем предъявлено
«обычный резюм ничего не пишет» ложно (1) текст исправлен, близнец export.go согласован, поставлен пин мой прогон: вызовов 3→3, скипнутая строка 19:48:13→19:48:14, три остальные не двинулись
механизм резюма назван неверно (1, затем 2) названы ОБА писателя с условием каждого; вынесено в §5а №9 как свойство места мутация recordSkippedStages красна; мутации двух неверных механизмов переживали
«the term would carry TWO renderings» ложно для сид-поверхности (1) проверка пере-сформулирована как РАЗНОГЛАСИЕ, три механизма разрешения названы греп отозванной фразы 0 при контроле 1; текст варнинга и e2e-ассерт обновлены
сравнение кортежа по сырым Src (1) свёрнуто через NormalizeSourceKeyи это оказалось неверно, см. следующую строку
свёртка ввела ложноотрицание, довод ложен (2) сравнение вернулось к сырому (зеркалит ключ хранилища), consolidatedRows строит строку с Src: c.Key; обе половины запинены мой замер: rows stored=2 против контрольного UNIQUE constraint failed; обе мутации красны
мой комментарий повторял misnomer «SIGNED» (1) исправлен, цена пропуска названа греп 0 при контроле 1
consolidatedRows не пиннился ничем (1) добавлен TestConsolidatedRowsCarryTheWindowAndTheAliases, усилен на круге 2 обе мутации красны с верным текстом; до пина переживали весь пакет
три дефекта корпусного прибора (1) классификация симметрична, мёртвая ветка снята, подсадка перебирает строки те же числа после починки: 142 книги, 13350 строк, подсадка 142/142
два дефекта прибора от линтера (1) разведено на две функции, rows.Err() возвращается golangci-lint0 issues.
двойной репорт в одном прогоне (1) НЕ подавлен, назван в доке как разные состояния термина мой прогон: collapse=1, merge=1, всего 3 строки WARN
пропуск по кортежу молчит на форме сид-строки по умолчанию (2) не чинится, названо ценой в доке, вынесено в §5а №7 замер: без until_ch: 20 → 0 при draft и approved, с ним → 1
тихий ноль glossaryRows (2) ошибка чтения банка логируется в коде r.Log.Warn на ветке ошибки
перебор «SIGNED half» (2) сужено до «подписанные строки на ДОВЕРЕННОМ ключе» memory.go dispositionFor/keyTrusted, singleHanKeyFired
стиль: довод трижды, история, план в коде (2) оставлен один носитель, остальное ссылкой; история и план сняты; чужой замер атрибутирован греп по каждой снятой формулировке 0 при ненулевом контроле
РЕГРЕСС: метка листа терялась при Key != Src (3) чтение переведено на tres.BankHolds[c.Key]; пин продлён через bankStopRows на кандидате {Key: 赵甲, Src: 趙甲} мутация обратно на c.Src красна: «the mark must reach the sheet for a candidate whose key differs from its surface»
отчёт описывал отменённую версию кода (3) §3(а) приведён к коду греп отозванной фразы 0 при контроле 1
нумерация §5а 1..7, 9, 8 (3) выправлена grep -oE '^[0-9]+\.' → 1 2 3 4 5 6 7 8 9
два абзаца доки под одним заголовком (3) разведены на «WHAT THE SKIP HIDES» и «WHO RESOLVES A SKIPPED PAIR» оба факта проверены по коду
варнинг glossaryRows обещал больше, чем делает (3) сужен до «whatever this call feeds», повторяемость названа зовётся и из scoreOpts, где затрагивается только якорь
сторона ЗАПИСИ карты не запинена (4) выделен один писатель bankHoldsByCandidate, продакшн и пин зовут его; фикстура различает все четыре кандидата на ключ обе мутации (cf.Key, cf.BankSrc) красны: «the mark must reach the sheet for a candidate whose key differs from its surface»
стдаут стопа показывал брата и прятал маркер банка (4) добавлена строка ⚠ bank holds: рядом с ⚠ contradicts: cmd/tmctl/render.go; пакет tmctl зелёный
абзац доки смешивал две популяции и врал про молчание (4) разведён: сид роняет эмиссия, дельту роняет loadAutoBank и ЛОГИРУЕТ, но словом «signed» §5а №1 приведён к тому же
дока поля и комментарий писателя расходились в слове (4) сведены на «keyed by the candidate KEY» греп по обоим местам
два числа отчёта не воспроизводились (4) пере-сняты командой; ложный контроль про Contradicts снят он печатается в стдаут — эта же находка дала строку выше
шов «писатель↔читатель» пережил и общего писателя (5) шов УБРАН: находки едут негруппированными, сопоставляет одна функция в файле-потребителе три мутации ключа сопоставления + «продакшн обходит хелпер» — все красны на одном пине
⚠ bank holds: в стдауте без пина, и брат тоже (5) TestRenderSignatureStopShowsBothDisagreements с контролем удаление любого из двух блоков красно с текстом про свой маркер
абзац обобщал дельту: до loadAutoBank доходит лишь НЕПОДПИСАННАЯ (5) уточнено одним словом unsignedEngineSurfaces оставляет approved-дельту сид-поверхностью
прибор проходил на пустом обходе, trimTo резал байты (5) пустой обход — t.Fatalf; срез рун-безопасен TM_CORPUS=/nonexistent → FAIL «a walk that found nothing reports the same zeros as a clean corpus»
шесть file:line отчёта протухли (5) пере-сняты грепом, каждый проверен 23 адреса резолвятся на заявленное (круг 6)
два счётчика отчёта протухли снова (6) ВСЕ числа сняты ОДНИМ проходом после последней правки круги 4, 5, 6 ловили это трижды — причина была в порядке, а не в счёте
обещание про src верно лишь для banknote-посадки (приёмка Д1) достроено до обеих посадок; свойство, на которое оно опирается, запинено идемпотентность 10/10 при контроле «4 из 10 входов меняются»; TestNormalizeSourceKeyIsIdempotent
гарантия approvedNeighbours только в комментарии (приёмка Д2) TestApprovedNeighboursAdmitsOnlySignedRows обе мутации фильтра красны со списком пролезших строк
отчёт противоречил сам себе через две секции (приёмка Д3) §3(ж) и §5а №8 исправлены, класс сужен до «пин узкий» греп целой фразы был предрешён — она живёт только в seeding.go

4-септимус. КРУГ 6 — СОШЛИСЬ

Круг 6 прогнал четыре мутации по перестроенному шву (три ключа сопоставления плюс «продакшн обходит сопоставитель инлайном») — все четыре красны на одном пине, e2e не ловит ни одной, что совпадает с заявленным разделением ролей пинов. Проверил и то, что перестройка ничего не потеряла: порядок находок тот же (предложение → firing-ключ → индекс банка), дублей нет по построению, детерминизм 200 прогонов — 1 различный вывод при 5 и 9 находках, КОНТРОЛЬ map-упорядоченной склейки — 189 различных.

Новых находок в коде пака нет. Осталось два:

  1. Шов-БЛИЗНЕЦ в коде, который пак не трогал: Contradictions и Conf пересекают ту же границу тем же способом, стороны согласованы, но ни одна фикстура не имеет кандидата с Key != Src — мутация любого из трёх ключей переживает полные пакеты pipeline, terminology и tmctl. Не регресс и не мой код; вынесен §5а №10.
  2. Два счётчика отчёта снова протухли — третий раз подряд, и причина не в счёте, а в порядке: я снимала числа до правок. Закрыто иначе, чем прежде: все числа отчёта пере-сняты ОДНИМ проходом после последней правки кода, и это записано рядом с ними.

Круг 6 сам поймал у себя ошибку до сдачи: прочёл чужой лог батареи как свой и объявил красноту. Назвал это в отчёте — то же требование, что канон предъявляет к сессии.

4-октавус. ДОФИКС ПО ПРИЁМКЕ — три пункта, все закрыты

Приёмка (три линзы, 14 находок, 0 блокеров, 3 major) подтвердила исполнением «репорт-онли», нетронутый снапшот и пере-посаженные мутации. Три пункта дофикса:

Д1 — обещание про src было верно для ПОЛОВИНЫ популяции, и я выбрала не сужать его, а достроить. Приёмка права: reverseSectionTerms эмитит Term{Src: c.Key} только для banknote-кандидата, а MINED-строка ложится с сырым m.Src (miner_emit.go:251). Замер решил, что чинить: c.Key — верный источник и там, и там, но по разным причинам. Мined-поверхность — подстрока УЖЕ нормализованного текста чанка (майнер везде читает c.NSource), поэтому её собственный ключ равен ей самой; проверено исполнением — NormalizeSourceKey идемпотентен на 10 из 10 проб, при КОНТРОЛЕ, что 4 из 10 входов он реально меняет (то есть ноль расхождений — свойство, а не молчание). ⇒ Комментарий достроен до обеих посадок, и свойство, на которое он теперь опирается, ЗАПИНЕНО (text.TestNormalizeSourceKeyIsIdempotent): без идемпотентности проверка сравнивала бы ложащуюся строку с источником, которого у неё нет, — молча, на mined-половине каждого банка.

Д2 — гарантия approvedNeighbours жила только в комментарии; теперь у неё пин. Мутация «убрать e.Status == "approved"» переживала три пакета. Траектория дорогая: это канон для промта ПЛАТНОЙ роли, и неподписанная строка, попав в «свидетельство», меняет байты, едущие к модели. Добавлен TestApprovedNeighboursAdmitsOnlySignedRows — краснеет от снятия ЛЮБОЙ из двух половин фильтра, с контролем, что четыре подписанных и отрендеренных строки дают четыре.

Д3 — утверждение отчёта опровергнуто, и опровергается оно моим же §9 п.2. Я объявила, что на текст варнинга S14 не стоял ни один тест, сославшись на grep = 0. Ноль был предрешён: я грепала ЦЕЛУЮ фразу, которая живёт только в самом seeding.go — прибор ответил на свой вопрос. Правда обратная: сообщение БЫЛО запинено подстрокой, батарея от расширения ПОКРАСНЕЛА, и правку того самого теста объявляет §9 п.2 двумя секциями ниже. Оба места исправлены; класс позиции §5а сузился с «пина нет» до «пин узкий»: подстрока стерегла одно словосочетание, а локализующая половина сообщения не была закрыта ничем.

Д3 — седьмой случай моего собственного класса за пак, и первый, который нашли не мои круги, а приёмка. Шесть кругов искали расхождение описания с кодом и не заметили расхождения отчёта с самим собой через две секции.

5. Таблица мутаций — правая колонка это ТЕКСТ падения, а не факт красноты

мутация текст падения восстановлено
mempostcheck: if present{continue}if !present{continue} «an OBEYED injection leaves its dst present, so the post-check has nothing to report: confirmed=1» sha256 совпал
гвард полисемии освобождает не-approved пару «status "draft": the polysemy livelock must be refused whatever the second row's signature» совпал
в сообщение возвращён совет «mark one status: auto» «the refusal must not offer a STATUS as a remedy — the guard ignores it and so does the wire» (×3) совпал
ConsolidationKeyConflicts: правая сторона только approved «an unsigned row is owed one rendering too: got 0 []» совпал
то же: предложение стреляет только своим Src «a contradiction reached through a shared alias must be reported: []» совпал
то же: снят пропуск по UNIQUE-кортежу «a proposal on the row's own UNIQUE key replaces it and cannot contradict it: [firing key "元始"…]» совпал
UnverifiedKeyConflicts: возврат к approved-only «want the approved×unsigned pair AND the unsigned×unsigned one, got 1» совпал
то же: из сообщения убраны окна «must be reported with both statuses» + «a conflict must name its firing key and both windows» совпал
проводка в схлопывании получает пустой банк «a rendering that disagrees with an UNSIGNED row of the same surface must be counted: {…BankConflicts:0…}» совпал
consolidatedRows теряет окно (до круга 1 ПЕРЕЖИВАЛА) «the candidate's window must reach the check: since_ch=0, want 7» совпал
consolidatedRows теряет алиасы (до круга 1 ПЕРЕЖИВАЛА) «the identity cluster must reach the check as alias keys: []» совпал
маркер строки банка удалён из рендера листа «the rendered table must carry the mark:» совпал
обеим находкам дан ОДИН маркер «the rendered table must carry the mark» совпал
находка подшита в поле само-противоречия «the contradicting row must be marked on the signature sheet: {…Contradicts:[unsigned draft "方源"→"Странник" [ch 1..20]] BankHolds:[]}» совпал
резюм пере-пиннит каждую обслуженную строку «an ordinary resume must not write an ok row: ch2/chunk0/edit moved …:07 → …:08» (×3) совпал
сравнение кортежа свёрнуто через NormalizeSourceKey (ПЕРЕЖИВАЛА до круга 2) «族长 against a stored 族長 is a pair the store admits, not a replacement: []» совпал
consolidatedRows берёт сырую поверхность вместо ключа посадки (ПЕРЕЖИВАЛА до круга 2) «the row must carry the source it will LAND with (the key), got "趙甲"» совпал
recordSkippedStages перестаёт пере-записывать скип «a SKIPPED row is re-derived and re-written by every run past it: ch1/chunk0/edit stayed at …» совпал

ЗЕЛЁНОЕ ДО КРУГА 2 → КРАСНОЕ ПОСЛЕ. Четыре мутации переживали пин, и каждая означала не дыру в пине, а неверное ОПИСАНИЕ или незапиненный фикс. Зелёный пин при ложноотрицании дороже красного, поэтому таблица отдельно:

мутация до круга 2 после что это значило
свернуть сравнение кортежа через NormalizeSourceKey зелено (весь пакет ok) красно: «族长 against a stored 族長 is a pair the store admits, not a replacement: []» мой фикс круга 1 не был запинен ВОВСЕ, и сам был неверен
consolidatedRows берёт сырую поверхность вместо ключа посадки зелено красно: «the row must carry the source it will LAND with (the key), got "趙甲"» фикстура пина имела Src == Key, поэтому выбор был не нагружен
флагнутая ветка runStageSequence не пере-записывает скип зелено заменена на recordSkippedStages — красно механизм в комментарии назван неверно; писателей ДВА
fast-path stagerun.go обслуживает скипнутые строки зелено ветка недостижима (у скипнутой строки пуст ContentHash) второй неверный механизм в том же комментарии

⚠ Одна мутация ОТБРОШЕНА, а не зачтена: «проводка удалена» не собралась, а сборочная ошибка — не поимка; пере-сделана компилирующейся.

6. Чем предъявлено — команды и вывод

  • Батарея после последней правки: make batteryMAKE_EXIT=0, ok пакетов 19 (+4 без тестов), строк FAIL 0, линтер 0 issues.; скипов 4, все названы батареей: TestMinerFullBookParity, TestCorpusBankKeyConflicts (мой opt-in прибор — батарея его видит и называет), TestHelperEventsRun, TestHelperKillLoop.
  • Дифф тестов исполнением (git diff -- 'backend/*_test.go' | grep '^[-+]func Test'): в отслеживаемых файлах добавлено 9, удалено 0; func Fuzz 0/0. Плюс по 1 в двух новых файлах (bankconflict_corpus_test.go, resume_updatedat_test.go) → итого +11 / 0.
  • Детерминизм: 200 прогонов на одном входе — различных выводов UnverifiedKeyConflicts 1, ConsolidationKeyConflicts 1; КОНТРОЛЬ — заведомо map-упорядоченная склейка на тех же данных даёт 8 различных (само число зависит от фикстуры; значимо только «больше одного»). Плюс -count=5 -race по новым тестам.
  • Корпус (TM_CORPUS=<репо>/books go test ./internal/pipeline/ -run TestCorpusBankKeyConflicts -v): .db walked=162, with a glossary table=161, without one=1, read-failed=0; books with a glossary=142, rows read=13350; ПОПУЛЯЦИЯ: книг хотя бы с одной неподписанной строкой=142, approved=1093 draft=11399 auto=858; книг с ЛЮБЫМ конфликтом=0; только approved×unsigned=0; с парой unsigned×unsigned=0; КОНТРОЛЬ: подсадка ловится на 142 из 142.0 книг из 142, и это «не встречается», а не «не смотрели»: 12 257 из 13 350 строк корпуса неподписанные, а форма столкновения не возникает потому, что все существующие двери роняют дубль по ПОЛНОМУ ключу (src,sense,since_ch,until_ch), а разные окна через них проходят. ⚠ Старое правило на корпусе тоже даёт 0 — S14 живёт в дереве без единого наблюдённого срабатывания; без этого числа «0» прочтётся как «новая половина бесполезна».
  • §5.3, греп по каждой отозванной формулировке (включая отозванные по находкам кругов 2, 3 и 4) — 25 из 25 дают 0, у каждой рядом контрольная фраза из того же файла с ненулевым счётом.

7. Двигает ли что-нибудь снапшот, хеш запроса, ключ манифеста, версию встроенных данных

Нет. Предъявлено:

  • Изменены только .go: 16 позиций git status по backend/ (14 M + 2 новых _test.go); configs/ и internal/lang/data/0.
  • git status по всем четырём testdata/ — пусто; КОНТРОЛЬ: голден-файлов в internal/pipeline/testdata/golden/6. Ни один голден не пере-снимался; сайдкар листа подписи голденом не накрыт (grep -rl 'BANK VERIFICATION TABLE' testdata/ → 0), его стерегут пять живых тестов, все зелёные.
  • Пины движения прогнаны поимённо ПОСЛЕ последней правки и зелены: go test ./internal/pipeline/ -run 'TestGoldenDeterminism|TestCutTagFollowsTheLangpack|TestManifest' -v14 PASS, 0 FAIL; go test ./internal/membank/ -run 'TestMemoryVersion|TestMaterializeMemoryVersion' -v5 PASS, 0 FAIL.
  • Новое поле листа подписи доходит ровно до ДВУХ человеческих поверхностей — сайдкара и стдаут-таблицы стопа: не-тестовых читателей BankHolds 2 (mining.gorenderBankStopTable, cmd/tmctl/render.go). Ссылок всего: BankHolds 12 в 4 файлах, BankHoldRows (носитель через границу) 5 в 3; КОНТРОЛЬ — у соседнего Contradicts 11 в 4. ⚠ Прежняя формулировка этого контроля («Contradicts дальше листа и лога не идёт») была НЕВЕРНА и снята по находке круга 4: он печатается в стдаут, и из-за той же находки мой маркер теперь стоит там же. ⚠ Числа пере-сняты одним проходом ПОСЛЕ последней правки: круги 4, 5 и 6 подряд ловили в отчёте протухшие счётчики, потому что я снимала их до правок, а не после.
  • Отдельным пином: диагностика НЕ входит в подписной документ (в signature map нет ни маркера, ни ярлыка строки банка; КОНТРОЛЬ — тот же файл содержит 青茅山 и terms:).
  • Обе проверки — только WarnContext; ни одна не возвращает ошибку и не меняет содержимого банка. Отказ (drop/stop) НЕ построен (П2).

8. §5а — «задумано против сделано». НЕ чинил, выношу списком

  1. mining.go:654 loadAutoBank(signed []store.GlossaryEntry), зовётся как r.loadAutoBank(in.entries) (bankmaterialize.go:125). Обещано именем параметра, докой (:648) и сообщением оператору (:691 «key held by the signed %q→%q»), что предложение движка отбрасывает ПОДПИСЬ. Исполняется: популяция — сид+ruby+дельта любого статуса; неподписанная строка отбрасывает предложение и печатается оператору как «the signed». ⚠ Формулировка круга 1 «ни одна проверка не говорит ни слова» ОПРОВЕРГНУТА кругом 4 и снята: дроп ЛОГИРУЕТСЯ (gatherBankInputsseeding.go), но текстом «held by a signed term» каким бы ни был статус держателя, — то есть оператору говорят НЕВЕРНОЕ, а не ничего, и это ровно предмет позиции. ⚠ Атрибутирую, а не присваиваю: своим прогоном исходный случай я не воспроизвела — моя фикстура на since_ch: 0 дала РАЗНЫЕ кортежи (обе строки легли, обе проверки сработали: BankConflicts=1, collapse=1, merge=1), а вторая итерация упёрлась в гейт пере-оплаты, потому что переиспользовала тот же проект. Проверено мной только по коду: held в loadAutoBank строится из параметра, которым передаётся in.entries (bankmaterialize.go:125), то есть из строк ЛЮБОГО статуса.
  2. terminology.go:873 и :941обе канон-проверки пропускают пару с РАВНЫМИ источниками. Проверочную половину закрыл сегодня; якорная осталась: роль не показывают, как книга уже зовёт поверхность, которую её просят перевести. Это меняет содержимое запроса ⇒ хеш ⇒ деньги, в пак не входит.
  3. terminologist.go:257 против mining.go:553 — фильтр «поверхность уже в банке» стоит только на ЭМИССИИ. Роль и классификатор ОПЛАЧИВАЮТСЯ за поверхности, которые банк уже несёт.
  4. bankmaterialize.go:139-141 — комментарий на вызове говорит «two DIFFERENT approved terms», тогда как ApprovedSharedKeyCollisions собственной докой заявляет, что same-src пары не пропускает.
  5. mempostcheck.go:91 против :122 и :130 — дока Shown говорит «how many unsigned rows were actually PUT IN FRONT of the model here», а sticky-перенос continue-ится ДО счётчика. Имя метрики шире её смысла.
  6. internal/pipeline/bankmaterialize.go:132 — remark оператору «auto-bank rows dropped: their key is already held by a signed term (the signed term wins)». Та же ложь, что в loadAutoBank: держателем ключа может быть неподписанная строка, и оператор увидит её названной подписанной.
  7. internal/membank/memseed.go, пропуск по UNIQUE-кортежу — сид-строка с окном ПО УМОЛЧАНИЮ и без sense делит кортеж с banknote-предложением (у обоих since_ch 0), поэтому самая частая форма рукописной сид-строки против выработки роли молчит, каким бы ни был её статус. Замер круга 2: та же фикстура без until_ch: 20BankConflicts=0 и при draft, и при approved; с until_ch: 20 → 1. На провод это не влияет (предложение отбрасывается, двух форм там нет) — теряется строка на ЛИСТЕ ПОДПИСИ. Закрытие требует правила «заменённая строка движка против отброшенного предложения», а колонка Source его не даёт: дельта владельца и авто-банк движка обе читаются mined.
  8. Пины на операторские сообщения есть, но узкие и несистемные — носитель internal/pipeline/seeding.go:73. Текст варнинга S14 был закрыт ПОДСТРОКОЙ в pipeline.TestUnsignedConflictIsReportedByTheRun, и расширение правила его честно покраснило; но подстрока стерегла одно словосочетание из всего сообщения, поэтому локализующая половина (обе строки, оба окна, firing-ключ) не была закрыта ничем и появилась только этим паком. ⚠ Прежняя формулировка этой позиции («не был закрыт ни одним тестом, grep = 0») была НЕВЕРНА и снята приёмкой: греп искал целую фразу, живущую только в самом seeding.go. Класс остаётся, но он про ПОЛНОТУ пина на текст, а не про его отсутствие.
  9. internal/terminology/terminology.go:993 и internal/pipeline/mining.go:451 — ШОВ-БЛИЗНЕЦ того, что бил меня три круга, живёт рядом и НЕ ЗАПИНЕН. Поля Contradictions и Conf пересекают границу файла тем же способом: ключ выбирается по разу с каждой стороны (Contradictions — по c.Src у писателя и читателя, Conf — по c.Key у обоих). Сегодня стороны согласованы, но ни одна фикстура не имеет кандидата с Key != Src, поэтому мутация любого из трёх ключей переживает ПОЛНЫЕ пакеты pipeline, terminology и tmctl (замер круга 6). На проводе не меняется ничего — теряются метка ⚠ contradicts и порядок «least sure first» на листе подписи у banknote-кандидатов с традиционным/кана-написанием. ⚠ Строки паком не тронуты, это не регресс; свой шов я убрала целиком (§4-секстус п.1), а этот выношу, потому что он того же класса и чинится десятью строками рядом с существующим тестом.
  10. internal/store/chunkstatus.go вместе с internal/pipeline/waverun.go — ПУТЬ ЗАПИСИ СТАТУСА НЕ ЧИТАЕТСЯ ПО КОДУ, и это свойство места, а не невнимательность автора. Писателей скипнутой строки ДВА, и какой сработает, решает раскладка волны: recordSkippedStages (waverun.go) — для флагнутой РЕДАКТОРСКОЙ единицы, флагнутая ветка runStageSequence (там же) — когда в ОДНОЙ волне две и более стадии. Читающий chunkstatus.go не видит ни того, ни другого. Замер: три формулировки механизма подряд оказались неверными (в дереве до пака, в моей первой правке, в моей второй), и каждую поймала только мутация — прочитанная по тексту, а не по цвету.

9. Правки существующих тестов, вызванные ЗАКАЗАННОЙ сменой поведения (D39.183)

Расширение UnverifiedKeyConflicts заказано оркестратором (П1), поэтому два теста, описывавших прежнее поведение, — обслуживание, а не подгонка. Оба объявляю:

  1. membank.TestUnverifiedKeyConflicts утверждал len(got) != 1. Теперь 2, и второе нашлось В ЕГО ЖЕ ФИКСТУРЕ, лежащей в дереве с написания: draft «старейшина» против auto «глава клана» — пара неподписанных, которую никто не видел. Прежняя гарантия сохранена дословно; добавлены обе подписи, оба окна и firing-ключ в каждом сообщении, исключение approved×approved с контролем, «пара с двумя ключами — одна поимка».
  2. pipeline.TestUnsignedConflictIsReportedByTheRun утверждал подстроку "contradicts an approved term", которую расширение сделало ложной. Заменён на новый текст правила плюс требование локализовать неисправность: раньше проверялись две подстроки, теперь пять.

Куда уехала гарантия: «прибор видит противоречие с участием подписи» → «прибор видит любое противоречие, кроме двух подписанных, и называет обе строки так, что оператор может их найти».

Третья правка — bankfixpack_test.go, ассерт на текст варнинга схлопывания: текст пере-формулирован по находке круга 1 («DISAGREES with a row the bank already holds» вместо «contradicts…»), потому что прежняя формулировка обещала две формы на проводе там, где эмиссия предложение роняет.

10. Что НЕ удалось · что не проверено · где не хватило данных

  • НЕ измерено, производит ли обычная последовательность операций состояние строки 267. Замерена ДОСТИЖИМОСТЬ и предъявлено, что провода её несут; на живом прогоне не наблюдалось — пак $0.
  • Корпусный ноль — про корпус, не про мир. 142 книги — почти целиком одна книга в множестве прогонов.
  • Не мерил объём вывода при массовом срабатывании: маркер листа подписи предъявлен на фикстуре в 3 кандидата.
  • Якорная половина находки §5а №2 не закрыта (роли не показывают существующую форму) — меняет запрос ⇒ деньги.
  • Двойной репорт не подавлен — назван и вынесен решением оркестратора.
  • Вопрос §4.1(в) «варнинг → стоп» не решал (по промту пинг; оркестратор развёл «видеть» и «делать» по уровням и завёл строку бэклога).
  • Чужие зоны: в дереве параллельно правится platform/ — не трогал; при лендинге коммитить только backend/ pathspec-формой.

11. Что я сам считаю слабым местом

  1. Три круга самопроверки нашли 31 находку В МОЕЙ РАБОТЕ. Пять — ложные утверждения в комментариях, то есть ровно тот дефект, который пак чинил; chunkstatus.go я написала неверно ТРИЖДЫ подряд (сначала «резюм не пишет», потом верное «пишет» с неверным механизмом, потом со вторым неверным), и каждый раз ловила только мутация, прочитанная по ТЕКСТУ. Вывод для приёмки: мои утверждения о поведении надо проверять исполнением так же, как чужие. И отдельно самое неприятное: одну находку внесла МОЯ ЖЕ ПРАВКА ПО НАХОДКЕ — фикс круга 2 был верен в функции и сломал доставку этажом выше, потому что я запинила изменённую функцию, а не путь до потребителя. Правка по ревью — такой же новый код, как всякий другой.
  2. ConsolidationKeyConflicts и расширенная UnverifiedKeyConflicts частично перекрываются, и это теперь ИЗМЕРЕНО (§4 п.7), а не предположено. Довод в пользу двух мест реальный (разные популяции), но «одно знание — один носитель» соблюдено не идеально.
  3. Мой довод про UNIQUE был ЛОЖЕН, и выяснилось это только на круге 2 — прогоном, которого я на круге 1 не сделала. Я сослалась на схему вместо того, чтобы её спросить; схема ответила иначе (ключ сырой, трад/упрощённая пара — две законные строки, обе инжектятся). Урок шире места: формула «доказано схемой» стояла в моём отчёте там, где честно было «не мерено».
  4. Мой e2e-тест обходил дыру подобранным значением: until_ch: 20 уводит сид-строку с кортежа предложения, без него проверка молчит (§5а №7). Это тот же класс, что «тест утверждает не то, что думает», и вынести подобранное окно должна была я, а вынес круг 2. Плюс маркер предъявлен на кандидате, которого в подписном документе НЕТ (方源 — сид-поверхность): адрес верный (стоп-таблица содержит всех кандидатов), но случай «противоречие у термина, который владелец реально подписывает» отдельным тестом не покрыт.
  5. Комментарий в waverun.go цитирует ЧУЖОЙ замер (1962/2283, строка 321). Не воспроизводил — атрибутировал.
  6. Три из девяти пунктов §5а — про terminology/mining, куда пак не посылал. Их количество говорит, что класс «описание шире/уже поведения» в этих файлах не разобран, а я прошёл по касательной.

11-бис. Дерево на момент сдачи

git status --short -- backend/ docs/PROGRESS.md (позиций по backend/18: 16 M + 2 новых):

 M backend/cmd/tmctl/render.go
 M backend/cmd/tmctl/render_test.go
 M backend/internal/membank/mempostcheck.go
 M backend/internal/membank/mempostcheck_test.go
 M backend/internal/membank/memseed.go
 M backend/internal/membank/memseed_test.go
 M backend/internal/pipeline/bankfixpack_test.go
 M backend/internal/pipeline/disposition.go
 M backend/internal/pipeline/export.go
 M backend/internal/pipeline/mining.go
 M backend/internal/pipeline/miningstop_join_test.go
 M backend/internal/pipeline/seeding.go
 M backend/internal/pipeline/terminologist.go
 M backend/internal/pipeline/waverun.go
 M backend/internal/store/chunkstatus.go
 M backend/internal/text/norm_test.go
 M docs/PROGRESS.md
?? backend/internal/pipeline/bankconflict_corpus_test.go
?? backend/internal/pipeline/resume_updatedat_test.go

Индекс пуст (git diff --cached --name-only → пусто). Чужого в списке нет: параллельно правится platform/ — не моя зона, не трогала. Не коммичу — лендит оркестратор, pathspec-формой по backend/ и моей секции журнала.

Батарея снята ПОСЛЕ последней правки, и это предъявлено, а не заявлено: find backend -name '*.go' -newer <лог батареи>0; КОНТРОЛЬ find … -newer <маркер часовой давности>5.

11-тер. Заявление о завершённости

Работа завершена, править больше не планирую. Критерий проверяется механически:

  1. Исход у каждого пункта заказа — таблица §0, пунктов без исхода нет.
  2. Круги сошлись, и приёмка добавила три пункта дофикса — все закрыты (§4-октавус). Круг 6 дал «сошлись»; всё найденное кругами 16 и приёмкой закрыто поимённо таблицей §4-тер. Два остатка круга 6 не в коде пака: пред-существующий шов-близнец вынесен §5а №10, счётчики пере-сняты.
  3. Числа сняты после последней правки, каждое командой. Батарея MAKE_EXIT=0 (19 пакетов ok, 0 красных, линтер 0 issues., 4 названных скипа); что она позже последнего касания кода — предъявлено: find backend -name '*.go' -newer <лог>0 при контроле 3, и с тех пор изменён только docs/PROGRESS.md.
  4. Мутации — таблица §5 полна (23 строк), выжившие названы отдельной таблицей «зелено ДО → красно ПОСЛЕ», отброшенная названа с причиной.
  5. Обещаний в отчёте нет — всё, что «надо бы», стоит секцией предложений ниже и решается оркестратором.
  6. Всё живое в дереве — отчёт, таблицы, замеры, ограничения; письма носителем не считаю.
  7. Дерево в безопасной точке — только моя зона, индекс пуст, не закоммичено, статус приложен выше.

12. Предложения (решает оркестратор, в паке НЕ сделано)

  1. Подавлять ли повторный репорт пары на ре-сиде в авто-режиме (§4 п.7). Резать надо слияние, не схлопывание.
  2. Показывать роли существующую форму поверхности (§5а №2, якорная половина) — меняет запрос и деньги.
  3. Фильтровать кандидатов роли по банк-поверхностям (§5а №3) — снимает оплату за уже банкованные термины.
  4. Ставить пины на ТЕКСТЫ операторских сообщений (§5а №8) — сегодня их нет системно, и расширение правила сделало один из них ложным при полностью зелёной батарее.
  5. Запинить шов-близнец Contradictions/Conf (§5а №10) — десять строк рядом с существующим тестом, фикстура с кандидатом Key != Src. Мой собственный такой же шов ловился ТРИ круга подряд, и это единственная причина, по которой я его называю: цена дыры измерена на себе.
  6. Довести разногласие до листа подписи и на форме сид-строки по умолчанию (§5а №7). Требует правила «заменённая строка движка против отброшенного предложения»; колонка Source его не даёт, потому что дельта владельца и авто-банк движка обе читаются mined. Это самая частая форма сид-строки, так что цена молчания не маргинальна.

ПИНГ ОРКЕСТРАТОРА 06.09 — мелочь, у которой не было носителя, и потому она здесь. backend/internal/bookfile/model.go:59 разросся до 183 знаков — единственная строка длиннее 120 в файле; удлинил её текст комментария, заландженный f1e9226. Правка на строку, линтер молчит, срочности нет. Записано потому, что моё решение «поправит зона при следующем касании» само носителя не имело, а следующего касания может не быть годами — и это ровно тот класс, который смена 06.09 ловила пять раз (находка, живущая только в письме). Возьми при любом касании файла; отдельного захода не стоит.

ПИНГ ОРКЕСТРАТОРА №22 от 05.09 про якоря — ИСЧЕРПАН В ТОТ ЖЕ ДЕНЬ, работать по нему НЕ НАДО. Зона починила всё коммитом e7d6b3f: counts.py --lint0 битых якорей, сверяемых по токену стало 200. ⚠ И нашла БОЛЬШЕ, чем было в пинге: из шести битых ПЯТЬ оказались старше её пака — их скрывало то, что backend/docs добавили в корни линта только 04.09; чей это дрейф, предъявлено замером, иначе пять чужих долгов записались бы ей. ⚠ Номера строк, продиктованные пингом, были НЕВЕРНЫ — зона пере-нацелила по СОДЕРЖИМОМУ и перевела ссылку в токенную форму, чтобы дальше её сторожил линт, а не человек. Что из этого стоит дороже починки — норма, найденная зоной у себя: она гоняла СВОЮ проверку якорей после каждого касания кода и ни разу не прогнала гейт, который уже стоит в репозитории. Два множества якорей и одна привычка — та, которую завела сама. Разбор — D39.202 п.3-бис.

Состояние зоны на 05.09 (вечер): активного промта НЕТ — пак «денежный стоп» ОТРАБОТАН и ПРИНЯТ С ДОФИКСОМ (акт D39.206, 81a89e9 + 616a8e4), промт в archive/prompts/ с баннером исхода; дерево backend/ чисто. Следующая работа зоны — строки 291 · 294 · 296. Прежняя редакция («на 31.08 активного промта нет, дерево чисто») читалась как текущее и приглашала следующего править чужое дерево. Ратифицированные лендинги зоны: входная дверь шва — D39.158 (d1eb8a9) · «тихая порча» — D39.164 (7d0c6f2) · «деньги» — D39.170 · гейт схемы — D39.173 · «писатель книги» — D39.175 (8adcb86) · «деньги и честность выдачи» — D39.182 (bb541a8) · ЗАКОН РАСКРЫТИЯ, ратифицирован владельцем — D39.181 · четыре строки бэклога закрыты тем же лендингом — D39.185. Диспозиция по D25.1 ратифицирована D39.175 п.2 (drift — не дыра файла; лестница — владельцу между паком и дверью).

Свободная работа зоны — строками бэклога: 246 (ЗАКРЫТА 04.09 актом D39.194 — копия потребителя приведена к производителю) · 247 · 232 · 233 · 197 (ресурс ушёл в фазу 1, строка не взята) · 228 · 229 · 230 · 141-остаток · 131. ⚠ Строк 231 и 236 в таблице БОЛЬШЕ НЕТ — 231 съел пак «деньги», 236 сужена D39.175.

Прожитая проза зоны за 2431.08 СНЯТА отсюда — история живёт слайсом archive/PROGRESS-2026-08-backend.md и телами нот выше; читать её не надо. Доказательная база пака «деньги и честность» и ВСЕ его пинги — файлами зоны: backend/docs/MONEY_HONESTY_REPORT.md (§7 — пинги оркестратору, §9 — экземпляры закона по одному, §0.1 — батарея ИСПОЛНЕНИЕМ, §5.1 — разложение покупок П1/П2/П3: ось пере-покупки терминолога = БАЙТЫ БАТЧА, а не сдвиг снапшота — это и есть «пинг №2», которым D39.185 п.1 адресует сюда; §6.2 — адверсариальный проход), backend/docs/DISCLOSURE_LAW_DESIGN.md, backend/docs/MONEY_HONESTY_PLAN-NOTE.md; промт — archive/prompts/BACKEND_MONEY_HONESTY_SESSION_PROMPT.md.

05.09 — ОТЧЁТ пака «ФОРМАТЫ И ЧЕСТНЫЙ СЛОВАРЬ» (сессия textmachine-main-fe, промт CHAPTER_STRUCTURE_SESSION_PROMPT.md)

Полный отчёт — backend/docs/CHAPTER_STRUCTURE_REPORT.md. Здесь только несущее. Денег $0.

Гейт §3 взят по ветке (а) на ВОСЬМИ исходниках из восьми: id глав и номера байт-в-байт, structure не изменился. Двинулось ровно заказанное — key и сегмент cutTag внутри unit-id при неподвижном префиксе id главы (c3aa4cbbb53de134:d4fb75e2:0c3aa4cbbb53de134:1b30b1dd:0). Батарея: make battery EXIT 0, 19 пакетов, 0 FAIL, линтер 0 issues, скипов 3 — те же три, что и до правок.

Построено: данные структуры ИСТОЧНИКА со своим загрузчиком и лестницей (файл языка → CJK-дефолт по скрипту → честный none) · компонент Structure в cutInputs и в ключе манифеста · четвёртое значение delimited и КОНКУРЕНЦИЯ свидетелей вместо сложения · EPUB nav/NCX с правилами прикрепления и счётами · title_raw аддитивно · бамп chunkerVersion v6→v7 с пере-захватом голдена.

Дрейф ingest↔chunker был ЖИВОЙ, а не гипотетический (замерено до кода): ингест резал по пяти юнитам 章节節回話 из embedded cjk-section.txt, чанкер — по четырём 章节節回 из пар-файла, и комментарий ingest.go, утверждавший «ONE source, no ingest↔chunker byte-drift», описывал намерение, а не код. Пак его ЗАКРЫЛ, а не предотвратил: cjk-section.txt не тронут ни строкой, чанкер начал читать ЕГО.

ГЛАВНОЕ, ЧТО СТОИТ ДОРОЖЕ КОДА — заказ содержал ЦИКЛ, и существующий тест его не ловил. Решить «есть ли шапки» нельзя до нейтрализации \f: шапка сразу за ним лежит на ОДНОЙ строке с прозой предыдущей главы и отвергается двумя предикатами сразу. При наивном порядке глава теряется МОЛЧА, а doc.Structure остаётся ВЕРНЫМ — то есть тест, проверяющий только ярлык, проходит над потерей. Класс D39.205. Предъявлено посадкой: наивный порядок красит TestTXTHeaderRightAfterAFormFeedIsNotLost («chapters = 2, want 3»), а тест провенанса при этом ЗЕЛЁН.

Шесть находок до кода, все приняты и внесены в промт (24f02bb · 23b00a3 · 5a502e7 · cd55329). Кроме цикла и дрейфа: гейт был недостижим по построению (требовал байт-в-байт манифест, а пак сам заказывает сдвиг cutTag); langpack_root 20 конфигов из 31 указывает в дерево ветки polygon; стенд отстал от движка — стенд-конфиг даёт манифест ровно для 1 исходника из 8 ({{genre}} ретирован и жив в шести промтах polygon, mined_delta/mined_rejects — в 17 конфигах из 31, поля stm_depth/overlap_tokens исчезли).

Норма, купленная сменой трижды за день: счёт по ИМЕНИ и счёт по СОДЕРЖИМОМУ — разные замеры, и первый молча даёт зелень. Шапки книги уникальны, а НОМЕРА повторяются шестикратно (первый прогон дал «повторов 0» и был неверен); файлы разноимённы, а байты те же (исходников восемь, не девять). Меряй хешем, не basename.

Выжившая посадка, записанная с аргументом: переворот сортировки целей nav не покрасил ничего — starts читается как МНОЖЕСТВО, группировка идёт по spine. Комментарий поправлен на правду вместо красивого утверждения; сортировка оставлена как контракт поля, а не как несущее свойство.

Схлопнутые цели nav понижают провенанс до delimited (правка спеки, найденная сдачей): книга, пакующая несколько глав в один документ с якорями, объявляет больше глав, чем пак отдаёт, и назвать такой разрез declared значило бы выдать своё, более грубое, за слово формата — та же ложь, что говорил spine. Четырёхзначного словаря хватило, достраивать ничего не пришлось. Резка по якорям в пак не входит.

Ревью-вопрос проекта закрыт ИСПОЛНЕНИЕМ: TestANewLanguageCutsFromItsDataFileAlone — корейская книга без своего файла остаётся ОДНОЙ главой, с ko/structure.txt режется на ТРИ и несёт title_raw; один бинарь, один текст, разница только в файле данных.

Каталог мутаций 201 → 205. Две записи целили в предикаты, которые §1 приказал УДАЛИТЬ, и пере-нацелены на свойства, занявшие их место; три новые — на правила формата. Все шесть прогнаны: 6 RED, 0 неожиданных. ⚠ Полный прогон 201 записи НЕ делался (124 из них гоняют ./internal/pipeline/ по ~145 с); вместо него механически проверено, что у всех 205 записей цель ЖИВА.

ДОФИКС ПО ПРИЁМКЕ 06.09 — шесть обязательных находок, все подтверждены мной заново и все закрыты. Дороже прочих M-1: молчаливая потеря текста. Роль toc/cover, объявленная С ФРАГМЕНТОМ (href="c2.xhtml#pos"), исключала ВЕСЬ документ — а фрагмент значит «оглавление НАЧИНАЕТСЯ здесь внутри», а не «файл целиком служебный». Проза исчезала при уверенном ярлыке declared и молчащем логе. Форма уже стоит в EPUB владельца: у Kristoff type="toc" href="index_split_124.html#filepos2096584", и мой прогон после починки показывает там service_roles_inside_documents 1 — то есть ровно этот случай на живой книге.

M-2: тревога не приходила никуда. Из пяти счётов логировались два; 126 документов, схлопнутых в 6 глав-китов, печатали в stderr ноль байт. Починено не пятью вызовами, а ОДНИМ репортёром IngestNotes() и рефлексионным сторожем, который краснеет на любом новом неподключённом счётчике: пять мест — это пять шансов забыть шестой.

Замер EPUB владельца через новый путь (мой, не верификатора): Kristoff — 71 глава declared, из них 64 короче 200 знаков (min 18, медиана 29, max 397 878); isekai — 44 главы, 9 коротких; fifty_shades — 32 главы, 3 коротких. title_raw заполнен у 71/71, 44/44 и 32/32. Цена Kristoff названа: 64 единицы манифеста несут не текст книги, а строки заднего листинга, и пойдут в оплату как главы — вопрос владельца.

Объявление D39.183, замеренное: регэксп ингеста стал допускать пробел между маркером и цифрой, чтобы ингест и чанкер читали заголовок одинаково. Разница на всех стендовых файлах — ноль (蛊真人 2996→2996, голден 8→8, оба ja-txt без изменений).

Находка о СВОЁМ коде из дофикса: прежний resolveHref раскодировал href ДО среза фрагмента, значит литеральный # в имени файла (приезжающий как %23) обрезал имя. Два почти-дубля резолвера сравнивались друг с другом и расходились молча — «один источник на факт» я заказывал сам и сам же не выдержал. Сведены.

Каталог 205 → 210, пять новых прогнаны: 5 RED, 0 неожиданных.

04.09 — ОТЧЁТ вайр-батча «род · экран цели · заголовки инъекций» (сессия textmachine-main-7e, промт BACKEND_WIREBATCH_SESSION_PROMPT.md)

ПЕРВОЙ СТРОКОЙ, потому что промт этого требует: internal/lang/data/ НЕ ТРОНУТ НИ БАЙТОМ. Пункт 3 сделан снятием РЕНДЕРА в Go. Предъявление, а не утверждение: diff -r <(git archive HEAD backend/internal/lang | tar -xO) … идентично, и tmctl manifest --json из HEAD и из дерева на example/book.yaml дают ТОТ ЖЕ manifest_key e996b9d4f129006e9faa6237fb1635a82e32c06c056b195072fae15f582021f6 и ТОТ ЖЕ unit.id f8ad8c8f114997c5:3d2213f2:0 (средний сегмент — cutTag). ⇒ пере-чеканки unit.id нет, recut у платформы не сработает, unit_resolutions книги параллельного платного прогона целы.

Состояние: пять пунктов из шести закрыты, шестой (140) упёрся в факт развёртывания и вынесен решением оркестратору — см. §4. Дерево НЕ закоммичено, лендинг за оркестратором.

Батарея (предусловие, не отчёт). cd backend && make batteryMAKE_EXIT=0, golangci-lint 0 issues, ok в 19 пакетах, SKIP три и те же: TestMinerFullBookParity, TestHelperEventsRun, TestHelperKillLoop. Тесты. grep -rn '^func Test' backend --include=*_test.go | wc -l1105 → 1143, добавлено 39 (из них 10 — дофиксом приёмки). Удалённых имён ОДНО, и оно названо: TestEditorSectionFollowsProvenance — это ПЕРЕИМЕНОВАНИЕ, а не потеря. Его предмет (маршрутизация двух секций редактора по провенансу) упразднён пунктом 3 вместе с самими секциями; уцелевшая половина утверждения живёт под TestTheGenderDirectiveAsksTheMatchAndTheWireAsksNothingElse и стала СИЛЬНЕЕ — держит оба блока, а не один. Команда диффа: comm -23 <(git show HEAD:… ) … по пофамильным снимкам. Каталог мутаций. python3 -c "import json;print(len(json.load(open('backend/cmd/tmmutate/mutations.json'))))"92 → 105.


Пункт 1 — строка 210: род ПРОИЗВОДИТСЯ. ЗАКРЫТ, с честной границей доставки

Развилка выбрана ЧЕТВЁРТАЯ, которой в промте не было: род производит существующий фокус-проход КЛАССИФИКАТОРА (runClassifier), третьим полем ответа. Довод: ноль новых вызовов (проход уже гоняется по тем же кандидатам с теми же контекстами) при цели №5 «низкий COGS»; род — свойство сущности, выводимое из контекстов, то есть акт классификатора, а не выбор рендеринга; парсер классификатора позиционный и закрыто-словарный, тогда как третье поле терминолога — уверенность, вокруг которой написана деликатная развязка мис-сплита по живому дефекту «наставник 95%». Цена: двигается RequestHash ТОЛЬКО классификаторных вызовов; терминологические чекпоинты книг живы. Ратифицировано оркестратором.

Построено. Промпт пары prompts/zh-ru/classifier.md v2 — третье поле, закрытый словарь male|female|neuter|none. ⚠ hidden в словарь НЕ входит НАМЕРЕННО: «пол скрыт до раскрытия» — решение о сюжете и спойлерной политике книги, а не наблюдение по KWIC-строкам; ошибочная догадка де-гендерила бы обычного персонажа на всю книгу. Остаётся ручным, в сиде. none — полноценный ОТВЕТ, а не пропуск колонки: без слова для «рода нет» единственный способ это сказать — не писать колонку, что неотличимо от «модель перестала отвечать». Go: terminology.Genders + ParseTypes возвращает types, genders, stats; ReplyStats.BadGender/NoGender — два счётчика, потому что это два разных отказа; pipeline.attachClassifiedGender; miner.Term.GenderDeltaFile → сид-YAML → сайдкары → банк. Гарантия, которую держит тест: колонка рода НИКОГДА не стоит классу — значение вне словаря отбрасывается и считается, класс сохраняется (TestTheGenderColumnNeverCostsTheClass).

ГЛАВНАЯ НАХОДКА ПАКА: ЗАМКОВ ТРИ, И НАЗВАННЫЙ В ПРОМТЕ — НЕ СВЯЗЫВАЮЩИЙ. bankmaterialize.go держит ДВА банка: черновая волна выбирает по baseMemory, из которого строки Source:"mined" вычеркнуты ПО ПОСТРОЕНИЮ, редактор видит обогащённый. Авто-банк пишется как mined (mining.go:671), подписанная дельта — тоже (mining.go:896, дословно «override the seed loader's Source:seed → mined (base-excluded)»). ⇒ на ЧЕРНОВОЙ провод произведённый род не едет и не поедет: там нет самой СТРОКИ. Это не дефект — это денежный контракт D39.42 п.3: инъекция черновой волны байт-стабильна поперёк обогащения банка, иначе пере-снапшот платит две волны вместо одной. Не трогал и не предлагаю. Формулируй границу так и не короче: род производится авто-путём и доезжает до РЕДАКТОРСКОГО провода в том же прогоне, что его произвёл; на ЧЕРНОВОЙ не едет, пока цена двух волн не решена отдельно. Не «род построен».

Второй замок СНЯТ по ратификации оркестратора, и снят РАСЩЕПЛЕНИЕМ, а не целиком. Disp сворачивал два вопроса — СТАТУС строки и надёжность МАТЧА. D39.104 п.1 упраздняет разнобой по статусу («банк на проводе = закон независимо от статуса строки»), но про матч там нет ни слова и быть не может: род, приписанный не той сущности, — ошибка, а не неподписанность. Заведено поле PickedEntry.KeyTrusted + тип InjectionTrust{Disp, KeyTrusted}, который несёт ОБА факта через липкое окно (у липкого переноса нет своего ключа, и матч-половину, как и диспозицию, восстановить нечем). Род теперь гейтится KeyTrusted на ОБОИХ блоках; статус не решает ничего. Сквозное доказательство — три двери порознь, а не «работает» (internal/pipeline/gender_wire_test.go): (1) неподписанная строка на доверенном ключе НЕСЁТ род редактору в том же прогоне; (2) collision-prone матч не несёт НИКУДА, при ЛЮБОМ статусе (юнит-проверка: на zh ветка не срабатывает физически, ханьские ключи якорятся на 2, поэтому сквозной zh-фикстурой её достать нельзя); (3) на черновой провод род не попадает НИКОГДА — и утверждение перевёрнуто нарочно: откроет кто-то дверь 3 — тест покраснеет и заставит автора назвать, какую именно. Отрицательный контроль есть: TestASignedGenderBeatsTheProducedOne — сид владельца побеждает, и не порядком присваивания, а тем, что loadAutoBank роняет предложение движка на занятый подписью ключ. Команда: go test ./internal/pipeline/ -run 'Gender' -v.

Пункт 4 — ПРЕДПОСЫЛКА пункта 1 в бою. Род производится только когда включён classify_types. Без банкового контура в боевом конфиге род не производится ни при каком варианте развилки.

Пункт 2 — строки 113 → 46: база записана, экран построен. ЗАКРЫТ

113 — СТОП СНЯТ, все три порога пройдены. Корпус взят исполнением: все чекпоинты всех 162 БД стенда, через СОБСТВЕННУЮ предобработку движка (splitBanknotechecks.StripThink — тот текст, который видит гейт), дедуп по хешу, только отгрузочные роли (банк-роли исключены: их ответы законно состоят из исходных термов, и включив их, мерили бы исключение, а не гейт). Обход дал 1162 ответа: 30 off-target, 1132 здоровых — но ⚠ в РЕПОЗИТОРИЙ уехала ВЫБОРКА, и все числа ниже воспроизводимы над ней, а не над обходом: 74 строки, все 30 off-target плюс 44 ЗДОРОВЫХ, отобранных нарочно трудными (20 с высшей долей исходного письма, 15 с низшей долей целевого, 3 под полом улики, остальное — спред). Тексты в git не поехали, довод — в шапке offtarget_corpus_test.go. Разметка НЕ гейтом, иначе она была бы пересказом вердикта: off-target = доля КИРИЛЛИЧЕСКИХ букв < 0.5 — свойство ЦЕЛЕВОЙ стороны, независимое от проверяемого исходно-письменного гейта. Корпус разделяется полностью: здоровые все выше 0.9, off-target все ровно 0.0000, полоса между ними ПУСТА. Числа воспроизведены и совпали с опубликованными до знака: худший здоровый source-share 0.011655 (контракт называл 0.0117), запас 12.87× против порога 0.15 (контракт называл 13×), ноль ложных на 44 трудных здоровых (не на 1132 — над репозиторием проверяемо именно это), поймано 28 из 30 (контракт называл 18 из 20 на более узком срезе того же стенда — та же доля, те же два промаха). Промахи — два беглых АНГЛИЙСКИХ черновика на 4690 и 4811 букв, ровно те, что названы в EFFORT_HANDLE §3.1. Худшая здоровая доля ЦЕЛЕВОГО письма 0.9767, максимум у off-target 0.0000, самый короткий off-target 346 букв — все три числа контракта воспроизведены. Команда: go test ./internal/pipeline/ -run 'OffTargetCorpus|LiveEchoGate|LatinOffTarget' -v.

ЧЕГО ФИКСТУРА НЕ НЕСЁТ, и это мой выбор с ценой. testdata/offtarget-corpus.json несёт РУНОСЧЁТ каждого образца (всего рун, рун исходного письма, букв, букв целевого письма), происхождение, метку и шестидесятирунную голову для человека — но не тексты. Тексты — копирайтная вебновелла и её машинные переводы, которые репозиторий держит вне git намеренно (стенд версионируется отдельным репо, example/ возит собственный фрагмент по той же причине). Руносчёта достаточно ПО ПОСТРОЕНИЮ: обе проверяемые функции — отношения классов рун и ничего больше не читают, и тесты кормят НАСТОЯЩИЕ функции скрипт-верным суррогатом, собранным из счётчиков, а не считают арифметику вместо них. Названная потеря: детектор, который будет читать слова, n-граммы или орфографию, на этой фикстуре не измеряется — ему нужен повторный обход стенда.

46 — экран построен формой (а) плана §5.4 и заморозкой D39.92/D39.93. Отдельный пакет чистых функций internal/langscreen (вход: текст + скрипты цели; выход: ИМЕНОВАННЫЙ вердикт on_target|off_target|abstain + счёт и объём улики). Порог OnTargetFloor = 0.50КОНСТАНТА в пустом интервале, не тюнинг (гарантия Неймана–Пирсона на этом корпусе не покупается — D39.92 п.1а); пол улики MinLetters = 200 калиброван, а не выбран: самый короткий off-target 346 букв, ниже пола падают три здоровых. Носитель данных — lang.LangScripts, НОВОГО эмбед-файла не заведено. Флаг СВОЙ — FlagOffTargetLang, FlagCJKArtifact НЕ переиспользован (D39.93 п.2), явный вход в escalatable(), не retryable. classifierVersion v2 → v3, и версия правила langscreen.Version вплетена в литерал, так что правка ВНУТРИ модуля двигает снапшот сама, а не по дисциплине. Приёмочный критерий §5.4 шага 5 исполнен: офлайн-прогон по корпусу — экран новооткрывает РОВНО два ответа, оба английские, здоровых не двигает ни одного (в тесте это Fatal, а не Error: план требует СТОП). Вдвоём два правила ловят 30/30 при нуле ложных. Команды: go test ./internal/langscreen/ -v · go test ./internal/pipeline/ -run 'TargetScreen|TwoScreens|BankRoleReply' -v.

Вторая половина дыры закрыта тем же диффом: detectLatinInsertion теперь под c.TargetScriptNonLatin() (internal/checks/sanitizer.go). Правило существовало в прозе доккоммента и стояло только на пути репэйра; первая же латинописьменная цель уронила бы КАЖДЫЙ чанк чистой целевой прозы как «Latin insertion». Для ru вердикты не двигаются ни на байт (предикат истинен) ⇒ бампа версии санитайзера не требуется.

НАХОДКА, приехавшая ВМЕСТЕ с паком, а не до него. Экран и эхо-гейт обязаны молчать на ответах банк-ролей: их буквы — движковые идентификаторы и исходные термы, поэтому эхо-гейт флагал бы их (и флагал: verdict=cjk_artifact при bad_lines=0 на чистой пробе 6/6), а экран флагал бы ВТОРЫМ способом. Исключение было записано как role == roleTerminologist и КЛАССИФИКАТОРА не покрывало (13-tech-debt-anchors §Б-105) — латентно, пока ни один боевой конфиг классификатор не включал. Пункт 4 его включает. Поле переименовано в NonProseReply (оно про ФОРМУ ответа), предикат один — isBankRole, рядом со строкой, которую новая банк-роль и так обязана добавить в bankRoleSettings.

Пункт 3 — строка 134: рендер снят, данные не тронуты. ЗАКРЫТ

Выбор объявлен: снят РЕНДЕР в Go. Механизм, по которому выбор сделан: cutTag сворачивает lang.EmbeddedVersion(), injection.txt лежит в internal/lang/data/ ⇒ правка данных пере-чеканила бы unit.id всей книги → manifest_key → снос unit_resolutions у платформы (строка 198). RenderFormatVersion в cutTag НЕ входит — он фолдится только в снапшот. Предъявление — первой строкой этого отчёта. Текст заголовка не менялся вовсе, и это проверено, а не принято на веру: действующий editor_header БАЙТ-ИДЕНТИЧЕН арму AM-noclause пробы 18 (experiments/18-editor-wire-probe.md §0.3 дословно: «Закон БЕЗ оговорки = действующий editor_header без единой правки»). Оговорка области НЕ внесена (опровергнута §A.4). Что изменилось: маркер ⟨проверить⟩ не рендерится НИ В ОДНОМ блоке; секция editor_unverified_header не рендерится, две секции редактора схлопнуты в один закон-блок; неподписанные строки стоят в нём под тем же заголовком и ничем не помечены. Статусы строк и подписная таблица не тронуты (D39.104 п.1). RenderFormatVersion v3 → v4. Ревью-ось «маркер снят, а пост-чек жив» проверена: membank.Postcheck ключуется на p.Disp, маркера не читает — обработка Ambiguous цела, счётчики Shown/Followed живы. ⚠ Но их СМЫСЛ сузился, и это записано в код: они родились на проводе, который помечал строку и приглашал модель её отвергнуть; теперь неподписанная строка показана законом, отклонение — просто отклонение, а не «модель пользуется дарованным правом». Та же поправка внесена в доккоммент миграции v12, которая эти колонки завела. Операторские тексты, которые стали бы ложью, переписаны (не комментарии — то, что печатается человеку): две строки tmctl про «уедет к редактору с пометкой ⟨проверить⟩», строка Unsigned bank terms в report, WARN стопа майнинга, WARN конфликта с подписанным банком.

НАХОДКА, которую я НЕ ЧИНИЛ и которая теперь висит на строке 250 (носитель заведён оркестратором): строка данных ru glossary_header САМА ОПИСЫВАЕТ снятый маркер («строки с пометкой ⟨проверить⟩ — неподтверждённые кандидаты»). После пака помеченных строк на проводе нет, а заголовок продолжает объяснять модели пометку. Это не мёртвая строка данных (editor_unverified_header и unverified_marker — те просто перестают читаться, и обе оставлены ОБЪЯВЛЕННЫМИ полями, потому что их СТРОКИ остаются в эмбеде, а parseInjection отвергает незнакомый ключ), а ЖИВАЯ строка с висячей ссылкой. Чинится только правкой injection.txt, то есть ценой cutTag. По D39.104 п.1 клаузула становится ВАКУУМНОЙ, а не ложной; вред не измерен.

Пункт 4 — строка 140: контур внесён в c1. ЗАКРЫТ с НАЗВАННЫМ предусловием развёртывания

Внесено в configs/pipeline-c1.yaml: gates.banknote.enabled: true + prompt_override: ../prompts/zh-ru/translator-banknote.md на стадии draft со своим лейблом (D39.10: включение банкноты — ДВА согласованных изменения; сам гейт только СРЕЗАЕТ блок, инструкцию писать его несёт промпт) · gates.terminology (модель deepseek-v4-flash, reasoning: lowу рендер-фазы это вынужденно, на вендорском дефолте она сжигает бюджет размышлением и возвращает пустое тело) · classify_types: true · mining.contrast_path.

Суб-бюджеты — числа и их довод. Множитель ×4.47 чинит пере-пин цен DeepSeek и ТОЛЬКО его; прежние 0.05/0.02 размерены под десятиглавую пробу, а этот файл обслуживает книги целиком. Замер (строка 16, десять глав, июльские деньги ×4.47): терминолог $0.0257, классификатор $0.0344. Бюджеты КНИГО-ШИРОКИЕ и копятся по всем прогонам книги (store.RoleSpentUSD суммирует чекпоинты роли по всем её джобам), а кандидатное пространство терминолога зависит от того, какие чанки уже отчерновлены, — значит между покупками оно меняется, request_hash другой, и книга, проданная десятью покупками, платит десять книжных консолидаций. Пол ⇒ 0.257 / 0.344. Взято 1.00 / 1.00, запас 3.9× / 2.9×. ⚠ Первая редакция дала классификатору 0.50, то есть запас 1.45×, а комментарий рядом обещал «≈3×» — число одной величины под именем другой. Поймано МОИМ ЖЕ адверсариальным проходом, исправлено: по замеру классификатор ДОРОЖЕ рендера, и «половина» пришла из старых чисел, а не из измерения. Бюджеты остаются раздельными при равных значениях: разделение про то, чтобы перерасход одной фазы не голодал другую. Пин: TestTheBankRoleBudgetsClearTheirMeasuredCost — это ПОЛ, а не значение; поднимать можно свободно, опускать ниже замеренного нельзя.

ПРЕДУСЛОВИЕ РАЗВЁРТЫВАНИЯ, названное вслух: mining.contrast_path — единственный вход контура, которого нет в git. ОБА банк-роля живут ВНУТРИ стопа майнинга, и runBankMiningStop возвращается РАНЬШЕ построения хоть одного кандидата без корпуса контраста. Артефакт (jieba-словарь общей частотности, 5 МБ) под .gitignore намеренно, но ВОСПРОИЗВОДИМ — рецепт и sha256 запинены в docs/experiments/16-bank-mining.md. Носитель требования к рантбуку и слово оператора — строка 251 (заведена оркестратором).

Два гарда, которые делают «настроено и мертво» невозможным — и оба нашлись не по заказу, а по разбору:

  1. Загрузка отказывает, если гейт включён, а mining.contrast_path ПУСТ (internal/config/pipeline.go) — тот же класс «гейт, который не может выстрелить», который лоадер ловит везде.
  2. Наличие ФАЙЛА проверяется на ПИШУЩЕМ пути, рядом с CheckKeys (Pipeline.CheckMiningContrast, вызов в openRunner внутри forWrite). Место выбрано не случайно: os.Open внутри прогона стоит ПОСЛЕ оплаченной черновой волны, то есть развёртывание, забывшее артефакт, платило бы за волну, чтобы это узнать. $0-поверхности не трогаются (D20.4).
  3. ТРЕТИЙ гард добавлен по находке адверсариального прохода, и он закрывает дыру в моих же первых двух. У раннего возврата ДВА условия, и я гейтил только одно: r.pack == nilа нил-пак книга получает, если не объявила langpack_root вовсе или объявила корень без каталога своей пары («nil-and-run»). Такая книга могла нести полностью настроенный и забюджетированный контур и не исполнить из него ни строки. Конфиг-лоадер этого структурно не видит: гейт знает пайплайн, пак знает книга, и вместе они есть только в раннере. Отказ добавлен там, тоже только на пишущем пути.

Пункт 5 — строка 184(а): жанр выкинут. ЗАКРЫТ

grep -rl '{{genre}}' backend/prompts/ | wc -l6 → 0. Поле снято из канона брифа (BriefHash), {{genre}} снят из плейсхолдеров pipeline.Render — значит промпт-пакет пары, написанный позже с этим маркером, падает ГРОМКО на первом рендере, а не подставляет пустоту. Репо-гейт на ту же вещь: TestNoShippingPromptAsksForTheGenre. BriefHash двинулся у ВСЕХ книг (c2021b1b…4624529b… на голден-фикстуре) — это заказано D39.138 п.2в и внесено в общее окно пере-снапшота именно потому, что платится один раз со всем батчем. ⚠ Ключ genre: ОСТАВЛЕН ПРИНИМАЕМЫМ, и это не мягкость. Платформа пишет книге book.yaml ОДИН раз из шаблона оператора и никогда не перезаписывает, протаскивая незнакомые ключи насквозь — genre там назван явно (platform/deploy/README.md). Декодер движка строгий (KnownFields), поэтому удаление поля отказало бы в загрузке книгам, которые уже лежат на диске, посреди живого прогона соседней сессии. Идиома — та же, что у ретированного adult: false. Значение не читается ничем: TestARetiredGenreKeyStillLoadsAndReachesNothing держит и загрузку, и равенство BriefHash у двух книг, отличающихся только жанром. ⚠ Лейблы промптов бампнуты и леджер пере-записан (v1-reflowv2-reflow-nogenre, v3-discourse-reflowv4-discourse-reflow-nogenre): байты промптов уехали, а лейбл обязан следовать за ними — иначе два прогона под одним лейблом несравнимы, что этот гейт и ловит. Тем же касанием в свип леджера добавлен КЛАССИФИКАТОР: он был вне его, пока ни один боевой конфиг его не включал, а его промпт решает КЛАСС термина, то есть маршрутизирует имя в транскрипцию, а реалию в перевод. ⚠ genre: ранобэ НАМЕРЕННО оставлен в testdata/golden/book.yaml с комментарием «не прибирать»: это место, где терпимость к ретированному ключу упражняется на каждом захвате.

Пункт 6 — дофикс чужого пака + ФЧ-7. ЗАКРЫТ

Это остаток ЧУЖОГО наряда (D39.187 п.4), а не мой заказ — сессия, делавшая тот пак, не пережила рестарт окружения.

(а) Развилка операторской строки прибита со ВТОРОЙ стороны. Воспроизвёл сам: ДВЕ посадки в новый код VolumeStop.String() переживали всё дерево (проверено с GOFLAGS=-buildvcs=false, иначе cmd/tmctl падает на VCS-штампе копии и маскирует результат) — (1) развилка заголовка всегда истинна, (2) развилка заголовка спрошена про ПЕРЕНОС вместо ОСТАТКА. Обе печатают в смешанном состоянии «reached the END of the book … Still in the book: 1 unit(s) NEVER delivered». Прибито TestTheStopLineSaysTheGrantHeldWorkBackWhenItDid — таблицей из ДВУХ строк, потому что две потери теряются на разных состояниях: всегда-истинная падает на любой, а спрошенная-про-перенос только там, где перенос и остаток оба ненулевые. Записи каталога WB1, WB2. (б) Граница bound() прибита. Carried > 0Carried > 1 переживало: существующий тест переносит ДВА юнита. Прогон с ОДНИМ перенесённым на конце книги не отдавал отчёт вовсе — тихий лимит, анти-паттерн D39.165 §1б. TestOneCarriedUnitIsStillWorkOutsideTheGrant, запись WB3. (в) Три числа отчёта — ПРОВЕРЕНЫ И СХОДЯТСЯ на HEAD. D39.187 п.4(в) говорит «протухли снова»; пере-снял все три их собственными командами до своей работы: батарея EXIT=0 с теми же тремя скипами · ^func Test 1105 · каталог 92. Отчёт 03.09 называет 1105 и 92. ⇒ пункт (в) закрыт лендингом f8d3e9a, и остатка по нему нет.

ФЧ-7 — ВОСПРОИЗВЕДЁН и ПОЧИНЕН. Починка СВЕРХ заказа, объявляю. Промт заказывал проверку исполнением и починку только при воспроизведении. Первая попытка воспроизведения ПРОВАЛИЛАСЬ и это важно: после потолка фидер runWave перестаёт раздавать элементы, поэтому второй воркер паниковать не успевает. Нужна синхронизация, чтобы обе позиции были в полёте, — и тогда воспроизводится ровно как описано: runWave отдавал ТОЛЬКО панику, errors.As(err, &CeilingHalt) → false, errors.Is(err, errReserveCeiling) → false, terminal() падал в failed и события ceiling НЕ писал. Почему это дефект, а не размен: platform/internal/runs/reconcile.go читает событие потолка ПЕРВЫМ и дословно говорит «that survives ANY exit: the process may have been killed on its way out, and the fact does not become less true». PD-113 закрыт ДВУМЯ независимо отказывающими каналами; одна паника забирала оба. Починка узкая: runWave присоединяет к панике ТОЛЬКО *CeilingHalt — не context.Canceled (проверено посадкой: присоединение отмены роняет TestWaveWorkerPanicSurfacesAsAFailingError, и правильно, крах не должен читаться как вызванный им же graceful stop); terminal() проверяет панику ПЕРЕД потолком, пишет событие ceiling и исход failed. Код выхода 1 и зеркало «исход = код выхода» не двинуты. Пины: TestACrashOverACaughtCeilingKeepsBothFacts, TestACrashOverACaughtCeilingStillAnnouncesTheCeiling, TestACrashJoinedWithACeilingStillExitsAsACrash.

ПЕРЕ-СКОУП строки 197 — как заказано. ФЧ-1/4/5 закрыты паком «число согласия» (D39.187). ФЧ-6 сверен кодом и выглядит закрытым: отказ проекции репортится базисом, отчёт не валится (internal/pipeline/status.go, греп RebillBasisFailed). ФЧ-7 закрыт этим паком. ФЧ-2, ФЧ-3 и ФЧ-8 НЕ ПРОВЕРЕНЫ НИКЕМ и остаются живым остатком строки — см. секцию «Что НЕ проверено».


Свобода и её разметка — отчёт ПО КАЖДОЙ строке таблицы промта

«Делай РОВНО так» — исполнено всё, отступлений нет: порядок 113 → 46 соблюдён (база записана ДО стройки экрана) · СТОП по фикстуре не сработал, все три порога пройдены с запасом · текст заголовка не менялся · статусы строк и подписная таблица не тронуты · нота бита спеку у FlagCJKArtifact — флаг СВОЙ · суб-бюджеты ×4.47 как ПОЛ, взято выше с объявленным доводом · жанр снят и из промптов, и из канона брифа · обе посадки дофикса краснеют · ФЧ-7 проверен исполнением (и починен сверх заказа — объявлено) · все запреты «Границ» соблюдены. «Решаешь сам и аргументируешь» — по каждому пункту решение и довод выше: развилка производства рода (§1) · второй замок — ВЫНЕСЕН пингом и ратифицирован оркестратором расщеплением, сам не снимал (§1) · данные в 134 — НЕ тронуты, объявлено первой строкой (§3) · числа суб-бюджетов (§4) · форма фикстуры 113 (§2, с названной ценой) · форма тестов и записей каталога · порядок работ (6 → 5 → 3 → 1 → 4 → 2, голден один раз в конце). Границы: manifestVersion, StreamVersion, схема хранилища и версия контракта НЕ двинуты (предъявлено tmctl manifest) · новый эмбед-файл не заведён · FlagCJKArtifact не переиспользован · семантика переноса слота не тронута · строки 131 · 105(а) · 14 · 119 · 124 · 115 · 160 · 161 · 142 не брались · чужие зоны, .env и соседний worktree не трогались.

Самопроверка исполнением

1. Дифф ^func Test ПОФАМИЛЬНО. grep -rn '^func Test' backend --include=*_test.go | wc -l1105 → 1143, добавлено 39. Удалённых имён ОДНО: TestEditorSectionFollowsProvenance — переименование, разбор в шапке. 2. Голден пере-захвачен ОДИН раз, маскированный дифф разобран построчно. 22 строки провода + 252 версионных. Диспозиций, флагов и chunk_status не двинулось ни одного (diff по этим строкам пуст; 252 строки до и после). ⚠ Поправка к моей же формулировке, найденная адверсариальным проходом: сказать «финальные тексты не изменились» было БЫ неверно. final_text изменился на всех 8 chunk-строках и stage_text на 22 — но ровно на ТОКЕН ХЕША, который фейк-провайдер эхом вкладывает в свой ответ, то есть следствием сдвига запроса, а не сменой вердикта. Точная формулировка: вердикты не двинулись; каждый финальный текст отличается только эхом хеша запроса.Вторая поправка того же прохода: в ГОЛДЕНЕ двинулись brief_hash, classifier_version, render_format_version и prompt_sha256 ЧЕРНОВОЙ стадии — а memory_version и prompt_version НЕ двинулись (у фикстуры свой лейбл v-golden, а токен фолда неподписанных строк заморожен намеренно). Мой первоначальный перечень осей был шире фактического. memory_version двигается на книге с гендерными строками, а не в этой фикстуре. 3. Собственные посадки ВНЕ шести пунктов — 8, механизмом cmd/tmmutate на копии дерева. 6 красных, 2 ПЕРЕЖИЛИ и НЕ чинены (вне заказа, носитель — строка 252): StickyDepth = 2 → 1 не ловит никто · priorityRank, отбрасывающий приоритет доверия в бюджете инъекции, не ловит никто. Третья пережившая — cutTag без lang.EmbeddedVersion() — ПОЧИНЕНА по своей инициативе, потому что на этом компоненте стоит весь довод пункта 3 (TestTheCutTagActuallyCarriesTheEngineData, TestEveryCutInputMovesTheTag, запись WB4; cutTag разложен на cutInputs/tag() — рефактор байт-нейтрален, предъявлено сборками из HEAD и из дерева). ⚠ Методическая заметка, стоившая ложного результата: tmmutate на копии дерева НЕ МОЖЕТ судить тесты cmd/tmctl, которые собирают бинарь, — копия не git-репозиторий и сборка падает на VCS-штампе, маскируя всё остальное. Гонять копию с GOFLAGS=-buildvcs=false. 4. Отдельный проход по СВОЕЙ ГОТОВОЙ работе свежим контекстом — ДВА агента, модель fable, оба read-only, с заданием ФАЛЬСИФИЦИРОВАТЬ шесть заявлений каждый (деньги и провод · вердикты и данные). Ноль не декларирую: они принесли шесть находок, и четыре я починил.

Находки собственного адверсариального прохода — что нашли и что с этим стало:

  1. bank-apply СТИРАЛ произведённый род — то есть ровно тот акт, ради которого стоп существует. termFromBank копировал только Type и Aliases; строка дельты уходила с gender: "", а loadAutoBank потом ронял авто-строку как занятый ключ. ПОЧИНЕНО: род переносится вперёд, как переносятся алиасы (это находка движка ОБ СУЩНОСТИ, а решение о РЕНДЕРИНГЕ не просили её выбрасывать); дверь по-прежнему род не ПРИНИМАЕТ. Пин TestApprovingATermKeepsTheGenderTheEngineProduced, проверен красным на копии без правки.
  2. Мой первый гард пункта 4 закрывал только одно из ДВУХ условий раннего возврата. Второе — r.pack == nil, а нил-пак книга получает без langpack_root или с корнем без каталога своей пары. Такая книга несла бы настроенный и забюджетированный контур и не исполнила бы ни строки. ПОЧИНЕНО третьим гардом в раннере (пишущий путь), где гейт и пак есть вместе — конфиг-лоадер этого структурно не видит.
  3. repairReGate звал classify БЕЗ TargetScripts — экран цели на пути ремонта воздерживался, судя везде: починка, вернувшаяся на другом языке, прошла бы ре-гейт, вся работа которого в том, чтобы спросить «это всё ещё пригодный ответ». ПОЧИНЕНО: ре-гейт зовёт тот же классификатор с теми же входами.
  4. classify_budget_usd: 0.50 давал запас 1.45×, а комментарий рядом обещал «≈3×». ПОЧИНЕНО: 1.00, запас 2.9×, и названо, что по замеру классификатор ДОРОЖЕ рендера.
  5. Тест TestTheLiveEchoGateKeepsItsMeasuredMargin проходил на фикстуре с ПУСТЫМ off-target классом: 0/0 = NaN, а любое сравнение с NaN ложно. ПОЧИНЕНО знаменателем-предусловием. Тем же касанием: суррогат целевой стороны привязан к записанному счёту (как уже был исходный), добавлены проверка target_script_letters ≤ letters и TestTheScreenConstantsStillSitWhereTheCorpusPutThem — константы langscreen сверяются с ДАННЫМИ, а не с константами (порог обязан лежать в пустом интервале корпуса, пол улики — не выше самого короткого off-target).
  6. allowshort_wire_test.go утверждал ОТСУТСТВИЕ маркера — после пункта 3 это утверждение не может упасть. Заменено на то, что фикстура ещё способна держать: allow_short доставляет строку ЦЕЛИКОМ, вместе с её родовой директивой. Плюс поправлены четыре комментария, ставшие ложью: decisions.go («род — сид-онли без автопроизводителя»), доккоммент langscreen про →en, BriefHash про исторический хеш, и три стейл-упоминания маркера в тестах зоны.

Что НЕ удалось и что НЕ проверено

⚠ Исходов ТРИ, и «не проверено» ≠ «опровергнуто» ≠ «сделано».

НЕ ПРОВЕРЕНО (никем, включая меня):

  • ФЧ-2, ФЧ-3, ФЧ-8 строки 197. Их я не открывал вовсе. ФЧ-2 — два докстринга reprice.go описывают не то, что делает код (детекция перебора односторонняя; «остаток несётся по счёту» неверно). ФЧ-3 — снятый закон approved-only продолжает утверждаться в докстринге теста и в backend/docs/D15.2-*.md:317. ФЧ-8 — докстринг TranslateBook про «каждый выход через terminal()» неверен для паники вне волны · комментарий dispatchCommands · шапка рига. Живой остаток строки 197.
  • Ничего в этом паке не проверено ПЛАТНЫМ вызовом. Ни одна модель не вызывалась: санкции на деньги у меня не было и я её не просил. Всё измерено на персистированных чекпоинтах стенда и на фейк-провайдерах.
  • Качество рода не измерено. Что классификатор реально отвечает в третьей колонке на живой книге — не мерено ни разу. Промпт написан консервативно (none объявлен самым частым и правильным ответом при нехватке контекстов), но верно ли он определяет пол — вопрос замера, а не стройки. ⚠ Это ПЕРВЫЙ кандидат в следующий полигон-пак: ось рода теперь производит данные, и ложный male поедет консистентно через всю книгу — то самое свойство, ради которого консистентность и строилась.
  • Экран цели не проверен на живом провале. Он ловит два образца, которые уже лежат в стенде; поведёт ли он себя так же на СВЕЖЕМ off-target событии — не мерено. Порог 0.50 стоит в пустом интервале и не калиброван (и это по D39.92 п.1а и не может быть иначе на этом корпусе).
  • Цена банкового контура в c1 на реальной книге не мерена. Числа суб-бюджетов — проекция от десятиглавого замера, не наблюдение. Первый же боевой прогон с контуром даст настоящие числа, и их надо сверить с полом.
  • Наличие корпуса контраста на БОЕВОЙ машине. Я его не видел и видеть не мог. Строка 251.

НЕ СДЕЛАНО СОЗНАТЕЛЬНО (с доводом):

  • Замок №0 не трогал — базовый банк исключает Source:"mined" по денежному контракту D39.42 п.3. Следствие названо в §1: род не едет на ЧЕРНОВОЙ провод и не поедет, пока цена двух волн не решена отдельно. Не моё решение.
  • ru glossary_header не тронут — висячая ссылка на снятый маркер, чинится только правкой injection.txt, то есть ценой cutTag. Носитель — строка 250.
  • Две пережившие мутации не чинены — вне заказа, носитель 252.
  • Строка 204 / PD-246: карту причин платформы не правил — чужая зона. Пинг отправлен напрямую (textmachine-main-34), она пере-сняла счёт своей командой и завела у себя; состав контрактного минора несёт оркестратору, потому что изобретать код замечания платформенная сессия не вправе.

НАЙДЕНО И НЕ ЧИНЕНО — ЧУЖИЕ ЗОНЫ (передаю фактом, не правкой):

  • Следствие починки ФЧ-7 на стороне платформы, которого я не предвидел. pgstore/sink.go кладёт событие ceiling в paused_reason, а runs/reconcile.go:1008 возвращает paused с exit_code = nil. ⇒ прогон, который УПАЛ поверх потолка, теперь приезжает paused и КОД ВЫХОДА теряется — крах становится невидим на строке прогона. Это лучше прежнего для пользователя (ему говорят «добавь денег», и это правда и действие), но хуже для операций. Взвесить и решить — не мне; несу как факт.
  • Стейл-упоминания снятого маркера вне моей зоны: platform/internal/runs/spawn.go:164 (прод-комментарий), platform/internal/runs/reconcile_test.go:723, platform/docs/DEFECT_REGISTER.md:412 (PD-277), eval/pilot/memory_eval.py:440-452 (заявляет «byte-synced with Go glossaryBlockHeader» и по-прежнему дописывает маркер построчно — зеркало провода в полигоне разъехалось).
  • platform/deploy/ ничего не знает о корпусе контраста (grep -rn 'contrast_path\|mining:' platform/deploy/ → пусто). Половина строки 251.
  • Дыра покрытия, найденная платной сессией и переданная мне (PD-441, её ряд): вызов, отменённый В ПОЛЁТЕ по книжному потолку, уходит веткой «No 2xx ever arrived: nothing was billed» → releaseReservation и нулевая цена в request_log, хотя замер 04.09 показывает отмены на 120756/156469/156470 мс — то есть запрос был выпущен и, скорее всего, оплачен. Латентность разводит два случая (2031 мс против 156 с). Я это НЕ чинил: stagerun.go в моей зоне, но это ДЕНЕЖНЫЙ путь и отдельный предмет, а не пункт вайр-батча. Заказ на него — отдельным паком.

ЧЕГО Я НЕ ДЕЛАЛ ПО ГРАНИЦАМ: не коммитил, индекс и историю не трогал; platform/ и eval/ только читал; соседний worktree не открывал; .env не читал.

ДОФИКС ПО ПРИЁМКЕ (04.09) — четыре пункта наряда, все закрыты

Класс, который приёмка вскрыла и которого моя самопроверка не нашла: СЕМЬ ЗАЯВЛЕННЫХ ГАРАНТИЙ СУЩЕСТВОВАЛИ ТОЛЬКО КАК КОД. Двенадцать её посадок пережили полную батарею. Это ровно образец D39.187 — тот же дефект, что этот пак чинил у чужого пака, повторённый мной. И нашёлся он там, где я сам сказал «ставь гуще», то есть карта слепых зон работает; чего у меня не было — это привычки сажать мутации на СВОЙ новый код, а не только на соседний.

Д1 — пять неприбитых гарантий прибиты, каждая тестом И записью каталога (WB5WB13, каталог 96 → 105, все красные одним прогоном). · F2, тяжелейшая: живая доставка строки 46 не была прибита вовсеgrep -rn 'FlagOffTargetLang' --include=*_test.go давал ПУСТО. Модуль экрана был прибит офлайн (по руносчёту фикстуры) и по своему пакету, а вердикт, ради которого он построен, на живом пути не проверялся ни разу: переживали и «экран всегда воздерживается» (Screen(out, nil)), и «chunkrun не передаёт TargetScripts», и снятие флага из escalatable() — прямое требование D39.93 п.2, без которого пойманный чанк молча ТЕРЯЕТСЯ вместо пере-атаки. Прибито: TestAnOffTargetCompletionIsFlaggedAndEscalated (вердикт + деталь + escalatable + !retryable + эхо остаётся эхом), TestTheScreenIsInertWithoutTargetData, TestTheRunnerHandsTheScreenItsData (через classifyOutput — ЕДИНСТВЕННЫЙ живой call-site, плюс исключение обеих банк-ролей). · F10: порог экрана не был ИСПОЛЬЗОВАН ни в одном тесте — случая с долей между границами не было, то есть константа могла быть любой. TestTheOffTargetThresholdIsUsed: 0.60 → ok, 0.40 → флаг. · F1: три гарда контураTestABankContourThatCanNeverFireIsRefused (лоадер судит КЛЮЧ и не судит ФАЙЛ) и TestTheContourRefusesAWriteRunItCannotExecute (обе половины раннего возврата: отсутствующий артефакт и нил-пак; с ПРЕДПОСЫЛКОЙ, что до порчи фикстура открывается, и с обязательной проверкой, что $0-чтение той же книги ПО-ПРЕЖНЕМУ работает — D20.4). · F5: гард TargetScriptNonLatin в санитайзереTestTheLatinResidueClassIsGatedOnTheTargetsOwnScript, обе стороны. ⚠ Названная узость: target-en.txt в репо нет, поэтому «латинописьменная цель» достижима только через ПУСТОЕ объявление (та же ветка wordScript == nil); строку с настоящим word_script latin тест получит в день, когда такая цель появится. · F6: исключение банк-ролей прибито было только юнитом на isBankRole; регресс до «терминолог-only» оставлял батарею зелёной. Теперь ловится через classifyOutput (WB7).

Д2 — $0-валидация плейсхолдеров ДО первого вызова. ДЕНЬГИ. Приёмка подтвердила исполнением то, что я принёс и не починил, сочтя вопрос про громкость: отказ на {{genre}} приходил ПОСЛЕ купленной черновой волны (stage=draft cost_usd=0.001820, edit wave started, затем отказ; drafts=1 edits=0). Вопрос был про МОМЕНТ, и я его не расслышал. Построено: CheckPlaceholders сканирует шаблон по тому же ЗАКРЫТОМУ набору, что подставляет Render — набор вынесен в одно определение (renderVals), потому что два списка это и есть способ, которым валидатор благословляет имя, которое рендер отвергнет. Вызов стоит в LoadPromptTemplate — единственной воронке, через которую проходят ВСЕ шаблоны: стадии, классы репэйра и обе банк-роли. Живой источник таких пакетов настоящий: grep -rl '{{genre}}' eval/ | wc -l27. ⚠ Заказанная смена поведения, объявляю (D39.183): TestRenderRejectsUnknownPlaceholder описывал отказ ОТ Render; отказ переехал на загрузку. Тест не ослаблен — он теперь держит ОБА рубежа (гейт на загрузке И собственный отказ Render), плюс что закрытый набор проходит целиком, плюс что отказ НАЗЫВАЕТ и маркер, и то, что движок принимает.

Д3 — закон-блок даёт ОДИН приказ на исходный термин. Ратификация исполнена ровно так. Дедуп переведён с (src,dst) на src. Довод, который я принимаю целиком и не смягчаю: пока у блока было два заголовка, две передачи одного термина были двумя РАЗНЫМИ высказываниями — «это канон» и «это неподтверждённый рабочий вариант»; мой же пункт 3 схлопнул их в два ПРИКАЗА об одном термине, а с разными родовыми директивами — в два противоречивых приказа об одном персонаже. Побеждает первая строка, и «первая» тут не случайность: Select отдаёт в приоритетном порядке, priorityRank ставит Confirmed раньше Ambiguous — то есть подписанная. Конфликт не спрятан, а РАЗВЕДЁН: движок уже пишет о нём WARN оператору (seeding.go), и это правильное деление — модель получает один закон, оператор получает разногласие. Отбрасывание строки на загрузке не бралось: это онтология банка, а нужна была узкая правка провода. Пин TestTheLawBlockGivesOneOrderPerSourceTerm кормит неподписанную строку ПЕРВОЙ (дедуп, хранящий первую строку ВХОДА вместо первой строки приоритета, прошёл бы фикстуру в естественном порядке) и отдельно держит, что ГОМОНИМИЧНЫЙ dst — два разных исходных термина — остаётся двумя строками.

Д4 — числа отчёта поправлены. F7: «ноль ложных на 1132» заменено на воспроизводимое над репозиторием — ноль ложных на 44 ТРУДНЫХ здоровых, с явным разделением «обход дал 1162/1132» и «в git уехала выборка 74 строк», и с описанием, как выборка отобрана. Это ровно класс «число одной величины под именем другой», который я чинил в пункте 4 и повторил в своём же отчёте. F8: расхождение шапки и секции самопроверки (1133/29 против 1135/31) снято — обе теперь 1143, добавлено 39.

F11 — РИСК ДИЗАЙНА, не чинен, называю (вход в калибровку). На латино-тяжёлом ЗДОРОВОМ русском экран цели даёт ложные off_target: русский с пиньинь-глоссами → 0.461, инструкции с shell-командами → 0.077. Ложный флаг ЭСКАЛИРУЕТСЯ, то есть стоит платного вызова. Корпус, на котором порог поставлен, — ОДНА сянься-новелла; жанр с системными окнами, кодом или плотной латинской терминологией не мерен вовсе. Перед первым платным прогоном книги другого жанра порог обязан быть пере-калиброван на её корпусе. Это не опровержение экрана (на измеренном жанре ноль ложных на трудных), это граница его калибровки.

Батарея после дофикса: MAKE_EXIT=0, 0 issues, 19 пакетов ok, скипы те же три. Голден пере-захвачен — 0 изменений (дофикс не двинул ни одного байта провода в фикстуре). Тесты 1105 → 1143, удалённых имён по-прежнему одно и то же переименование. Каталог 92 → 105, записи WB1WB13 красные.

КРУГ 2 ПЕТЛИ (D39.191) — НЕ ЗАМКНУЛСЯ: веер нашёл 21 пережившую посадку, все закрыты. Круг 3 обязателен

Условие замыкания жёсткое, и оно не выполнено: круг замыкается, только когда проход с НЕПУСТЫМ веером не нашёл ни одной пережившей посадки. Этот нашёл двадцать одну. Ниже — веер, все находки с диспозициями, что я перепроверила сама, и чего круг не покрыл.

Веер

Три источника, разные ракурсы. (1) Агент fable, read-only — ДОФИКС, которого свежий контекст не видел: CheckPlaceholders, дедуп по src, новые тесты гардов и экрана на ВАКУУМНОСТЬ. (2) Агент fable, read-only — НЕПОКРЫТОЕ, ровно по моему же списку слепых зон: volume.go (пункт 6, чужой дофикс), закон-блок на книге с НЕПОДПИСАННЫМИ строками, бласт-радиус InjectionTrust, свип леджера, мелкие поверхности. (3) МОИ собственные посадки — В ДАННЫЕ, чего в круге 1 не было вовсе: фикстура корпуса, prompt-labels.json, pipeline-c1.yaml, промпт классификатора, injection.txt. Посадок всего: 12 моих + ~26 агента A + ~60 агента B. Мои: 11 красных, 1 пережила.

Что нашлось — двадцать одна пережившая, по классам

А. ЖИВОЙ ДЕФЕКТ, внесённый моим же дофиксом (1). · Дедуп закон-блока по голому src ронял ВТОРУЮ ПОДПИСАННУЮ строку. Ключ уникальности банка — (src, sense, since, until), то есть одна поверхность законно несёт несколько подписанных канонов: 青山-фамилия и 青山-направление. Мой дедуп выбрасывал один из них МОЛЧА, при том что трансляторный блок продолжал рендерить оба — два провода разъезжались. Правило исправлено на то, чем оно должно было быть с самого начала: уступает НЕПОДПИСАННАЯ строка, и только подписанной; подпись не роняется никогда. Пин красный на возврате к старому ключу.

Б. ДЕНЬГИ (2). · ReachableModels не знал банк-ролей. buildClients пре-строит именно этот список, CheckKeys требует именно эти ключи — оба на ОТКРЫТИИ. Модель терминолога или классификатора, не заведённая в models.yaml или без ключа в окружении, проходила ВЕСЬ преflight и убивала прогон на стопе майнинга — после купленной черновой волны. Латентно, пока контур не жил в боевом конфиге; пункт 4 делает это живым. · Банкнотный канал покупает вывод, который на этой конфигурации никто не прочитает — единственный читатель за ранним возвратом. Не отказ (прогон корректен, срез делает свою работу), а предупреждение с ценой.

В. УТВЕРЖДЕНИЯ О СТРУКТУРЕ, ВЫДАННЫЕ ЗА ГАРАНТИИ (4) — класс, которого я в круге 1 не назвала. · «валидатор и рендер читают одну таблицу» — прибито только ПРИМЕРАМИ; валидатор-надмножество проходил всё; · «проверка стоит в единственной воронке и покрывает все пути» — все четыре пути загрузки промптов обводятся вокруг гейта, батарея зелёная. Моя же формулировка из отчёта по Д2; · «порог лежит в пустом интервале» — порог 0.50 → 0.45 переживает всё И НЕ ДВИГАЕТ ВЕРСИЮ: резюмнутый чанк пере-судился бы по порогу, за который никто не платил. ⇒ langscreen.Version теперь ВЫВОДИТСЯ из констант, classifierVersion стал var, правка порога роняет голден по построению; · «свип леджера покрывает обе банк-роли» — свип ходил по НАЙДЕННОМУ и никогда по ЗАПИСАННОМУ, поэтому удаление роли из свипа оставляло её запись сиротой, а промпт — неприбитым. ⇒ проверка сирот.

Г. ДАННЫЕ (1) — и это то, ради чего норма про посадки в данные написана. · Фикстура корпуса, размягчённая до красивого числа, проходила всё. Тест утверждает пол «не меньше 3×», а пол не измерение: обнуление исходных рун у ЕДИНСТВЕННОГО худшего здорового образца оставляло батарею зелёной и рапортовало запас ЛУЧШЕ, чем корпус когда-либо давал. ⇒ леджер записанных чисел (30/44 строк · 0.011655 · 0.976706 · 346 букв), по образцу леджера лейблов: пере-взять корпус законно, но это стоит правки здесь и фразы в отчёте, а не ничего.

Д. РАСЩЕПЛЕНИЕ Disp, прибитое только там, где две половины СОВПАДАЮТ (3). · липкий перенос, ПЕРЕ-ВЫЧИСЛЯЮЩИЙ матч-доверие, переживал всё: единственный пин использует строку, чей src И ЕСТЬ сработавший ключ, поэтому пере-вычисление совпадает с наследованием. Разводит их строка с ханьским src и коротким фонетическим АЛИАСОМ — там перенос re-trusted, и род едет к сущности, которой на странице может не быть; · липкий перенос, ВЫВОДЯЩИЙ доверие из диспозиции, тоже переживал: неподписанная строка на чистом ключе теряет род в момент переноса — дверь строки 210 в липкой форме; · диспозиционная ось priorityRank не отличима от статусной ни одной фикстурой. Это одна из ДВУХ, переживших круг 1, и теперь на ней стоит мой дедуп. ⇒ прибита состоянием, которое оси разводит: две ПОДПИСАННЫЕ строки, одна на collision-prone ключе, под связывающим бюджетом.

Е. ЧУЖОЙ ПАК (пункт 6), которого свежими глазами не видел никто (6). Из двадцати посадок в volume.go шесть пережили, и все шесть — в ОПЕРАТОРСКОМ ПРЕДЛОЖЕНИИ и в двух неотфикстуренных ветках reconcile: счёт «%d paying output unit(s)» без флагнутых (недо-счёт того, за что заплачено) · клауза про $0-попутчиков · развилка головы, спрошенная про LeftFresh вместо Left() · свободный юнит, флагнувшийся на резюме, посчитанный оплаченным · пере-деланный юнит, флагнувшийся и оставшийся В ОБОИХ счётчиках · и порядок bound() ДО reconcile, от которого корректность отчёта зависит СЛУЧАЙНО. Прибиты пятью тестами; последний — документирован в waverun.go с прямым указанием, какой «естественный рефактор» его сломает.

Ж. Прочее (4): липкие записи, исчезающие из закон-блока · глубина липкого окна · сироты леджера · injection.txt без родовой строки (последнее — уже красное, поймано TestDC3GenderInjection).

Что я перепроверила сама, а что взяла со слов

Перепроверила посадкой ДО починки (все, кроме одной): дедуп по src · порог экрана · валидатор-надмножество · обход воронки на пути классификатора · диспозиционная ось · липкий перенос (обе формы) · сирота леджера (обе формы) · липкая запись в закон-блоке · банкнотный канал · размягчённая фикстура. Взяла со слов: H2 (два ряда с одним id — недостижимо через стор), H7 (битый артефакт контраста молча даёт пустой контраст), и стейл-текст glossary_header — про него я уже знала. ⚠ И одна собственная ошибка, которую поймал каталог, а не я: первая редакция теста про ReachableModels читала pipeline-c1.yaml, где модель банк-роли СОВПАДАЕТ с моделью черновика, — то есть тест не мог упасть. Посадка сказала SURVIVED, я переписала тест на конфиг, где банк-модель своя. Механизм проаудировал мой пин; чтение бы не проаудировало.

Чего круг НЕ покрыл

  • Пункт 5 (жанр) и цепь рода end-to-end — ни один агент их не атаковал: я дала им дофикс и непокрытое, считая эти два закрытыми кругом 1. Остаются проверенными одним проходом.
  • $0-проекции на дефектной книгеstatus/report/export, реально отрендеренные: и мой тест, и посадки доказывают только, что КОНСТРУКТОР открывается.
  • Липкий перенос до РЕДАКТОРСКОГО провода сквозным прогоном — ни одна фикстура не гонит прономинальный чанк с переносом в edit-юнит; всё прибито на уровне membank.
  • Настоящая латинописьменная цельtarget-en.txt в репо нет; ветка достигается пустым объявлением, и тест это говорит.
  • eval/-харнессы — вне модуля бэкенда, не гонялись.
  • Сверка двух агентов между собой — снова не делалась.

Числа круга

Батарея MAKE_EXIT=0, 0 issues, 19 пакетов, скипы те же три. Голден БАЙТ-ИДЕНТИЧЕН тому, что был до починок круга (единственное движение голдена за круг — classifier_version от вывода версии экрана из констант; вердикты не двинулись). Тесты 1105 → 1156. Каталог 92 → 120, записи WB1WB29 красные одним прогоном. Удалённых имён по-прежнему одно — переименование TestEditorSectionFollowsProvenance.

КРУГ 3 ПЕТЛИ (D39.191) — ЗАМКНУЛСЯ ПО СОДЕРЖАНИЮ, НО НЕ ПО УСЛОВИЮ: веер нашёл 20 переживших посадок и 1 дыру исполнением, все закрыты

Условие замыкания не выполнено и здесь. Круг замыкается, только когда проход с непустым веером не нашёл НИ ОДНОЙ пережившей посадки. Этот нашёл двадцать — плюс дыру, найденную не посадкой, а исполнением. Ниже веер, все находки с диспозициями, что я перепроверила сама, и чего круг не покрыл.

Веер

Два источника, и это первый круг, где второй — не мой агент. (1) Агент fable, read-only, работавший в СВОИХ копиях дерева (рабочее дерево не тронуто — подтверждено им и сверено по git status): 68 посадок в семи предметах, 48 красных, 20 переживших, 0 несостоявшихся. (2) Круг оркестратора — независимый веер по тому же батчу, девять находок, пять новых для меня. По трём пунктам два веера сошлись НЕЗАВИСИМО (дедуп полисемии · порог без пина · класс структурных утверждений), и это первое за три круга свидетельство, что находки воспроизводимы между читателями, а не являются вкусом одного.

ГЛАВНОЕ: денежная дыра, которую круг 2 ОБЪЯВИЛ ЗАКРЫТОЙ, была открыта

Мой фикс круга 2 внёс банк-роли в ReachableModels() и на этом остановился. CheckKeys читает этот список ТОЛЬКО в лейбл-ветке. Безлейбловая книга — shipping-дефолт — идёт второй веткой, которая собирала модели стадий руками и про ворота не знала. Проверено исполнением: терминолог, классификатор и ремонт на провайдере с пустым api_key_env проходили префлайт целиком, CheckKeys возвращал nil. Прогон покупал черновую волну и умирал на воротах.

Почему тест круга 2 был зелёным поверх дыры: он утверждал СПИСОК, а не префлайт. Пин на списке не есть пин на проверке, которая его читает.

И вторая половина той же дыры: рантайм-список reachableModels() тоже не был прибит — посадка «только стадии» (без ремонта и банк-ролей) держала ВЕСЬ пакет pipeline зелёным. Причина — совпадение pipeline-c1, воспроизведённое в фикстурах: каждая фикстура ставит воротам model: fake-model, ту же модель, что у стадий. Закрыто: одно определение gateModels(), которое читают обе ветки CheckKeys и ReachableModels; тест зовёт CheckKeys, а не смотрит список; и фикстура, где банк-роль ходит СОБСТВЕННОЙ моделью, с пином на пре-строенной карте клиентов.

Что нашлось ещё — по классам

А. ЦЕЛЬ С CJK-ПИСЬМОМ НЕ ЭКРАНИРОВАЛАСЬ ВООБЩЕ (находка оркестратора). Гейт !isCJKTarget принадлежал ЭХО-правилу, а держал оба правила сразу. «Вывод в письме ИСТОЧНИКА» для →ja бессмысленно — верный перевод zh-книги полон ханьцзы; «вывод в письме ЦЕЛИ» отвечается прекрасно. Итог: →ja/→zh/→ko не судились ничем, при том что доккоммент langscreen обещал обратное. Это бьёт в цель проекта №2: на ревью-вопрос «заработает ли пара, которой в репо нет, без правки Go» ответ для CJK-целей был «нет». Экран вынесен из-под гейта, эхо-правило осталось под ним. Документированный предел супермножества (китайский вывод для →ja не флагуется) прибит как ПРОМАХ, чтобы никто не принял экран за защиту от zh-эха на →ja.

classifierVersion НЕ двигали — ратифицировано оркестратором. Для →ru поток управления побайтово тот же (!isCJKTarget истинно и до, и после, обе ветки в том же порядке), →CJK-снапшотов не существует, а строка в этом батче уже сдвинулась дважды и пере-снапшот уже предписан единым актом. Различитель на будущее: бамп должен любой смене, способной пере-вердиктить СУЩЕСТВУЮЩИЙ снапшот — не «кажется, безопасно».

Б. ПРОИЗВОДНОСТЬ ВЕРСИИ ЭКРАНА БЫЛА ЗАЯВЛЕНА И НЕ ДЕРЖАЛАСЬ (3 посадки). Доккоммент Version говорит «выведена по построению, поэтому сдвиг порога забирает громкий --resnapshot с собой». Не проверял никто. Посадка: переписать var литералом, который он сейчас печатает, и сдвинуть порог 0.50 → 0.45 — строка не двинулась, голден не двинулся, оба интервальных пина прошли (0.45 внутри пустой полосы), весь пакет зелёный. Резюмированный чанк пере-вердиктился бы порогом, за который никто не платил. Третья дверь: %.2f не выражает 0.504 — окно точности ±0.005. Закрыто: тест пересчитывает строку из констант, и round-trip-guard требует, чтобы напечатанный порог читался обратно тем же числом. Формат НЕ расширен намеренно — это стоило бы --resnapshot всем книгам за правило, которое не менялось; расширение теперь осознанный акт.

В. ГРАНИЦА СРАВНЕНИЯ, КОТОРУЮ НЕ ВЫРАЖАЕТ НИ ОДНА КОНСТАНТА. share < floor<= пережило весь пакет: ни одна фикстура не сидела ровно на линии. Прибито фикстурой ровно на 200 буквах, из которых ровно 100 целевых — доля 0.50 без плавающего люфта.

Г. ВАЛИДАТОР ПЛЕЙСХОЛДЕРОВ — ТРИ ДВЕРИ. (1) Сканирование только System-части пережило всё — каждая фикстура кладёт плохой маркер в системную половину, а самое вероятное место для автора — пользовательский хвост, где живут почанковые переменные. (2) Снятие проверки незакрытого {{ пережило. (3) Тест «равенства множеств» обходит placeholderNames(), то есть таблицу РЕНДЕРЕРА, и доказывает только «рендерер ⊆ валидатор»; дорогое направление — обратное, и оно было прибито четырьмя ЛИТЕРАЛЬНЫМИ словами, так что пятое слово проходило насквозь. Закрыто устранением, а не пином: валидатор ТЕПЕРЬ ЕСТЬ РЕНДЕРЕРCheckPlaceholders рендерит по настоящей таблице значений. Второго списка не существует, расходиться нечему.

Д. ЗАКОН-БЛОК: ПОДПИСЬ ПРОТИВ УВЕРЕННОСТИ (5 посадок). Подпись — это СТАТУС, а не уверенность матча: подписанная строка, сработавшая по сомнительному ключу, всё равно канон, которому уступают. Ключевание набора подписей на диспозиции пережило. Уступать должен ЛЮБОЙ неподписанный статус, а не только draftauto пишет майнер, то есть ровно та строка, ради подчинения которой правило и существует. Плюс: подписанная строка с ПУСТЫМ переводом не канон (иначе термин исчезает из блока), несимметричный TrimSpace разрушает набор, и однопроходная версия зависит от порядка. Отдельно — вакуумность в моём собственном тесте: его комментарий утверждал, что случай (1) держит независимость от порядка, а стоящий там же sortByPriority это утверждение обнулял. Комментарий исправлен, независимость от порядка вынесена в отдельный случай, который рендерит блок НАПРЯМУЮ, в обоих порядках.

Е. ЛИПКИЙ ПЕРЕНОС: ПОЛОВИНА ДИСПОЗИЦИИ. Перенос наследует обе половины, но пересчёт диспозиции ИЗ СОБСТВЕННОЙ ПОВЕРХНОСТИ строки пережил: в прибитой фикстуре src сам и есть сомнительный ключ, поэтому пересчёт воспроизводит тот же ответ. Разделяющая фикстура (ханьский src, сомнительный кана-алиас) существовала, но утверждала только KeyTrusted. Под посадкой перенос молча повышался до Confirmed — пропуск принудительного пост-чека и место повыше в бюджете, — а провод молчал, потому что половина доверия цела. Это D16.2-повышение в чужом пальто.

Ж. ЛЕДЖЕР КОРПУСА ПИНИЛ ЭКСТРЕМУМ, А НЕ ПОПУЛЯЦИЮ (5 посадок). Второй по трудности здоровый образец можно было смягчить, второй по низости целевой — тоже, а трудную строку — заменить числами лёгкой ПОД ЕЁ ЖЕ id: счётчики, экстремумы и множество id держались. И у интервала не было записи про ВТОРУЮ сторону: доля off-target могла уехать 0.000 → 0.490 при всех зелёных тестах, и порог 0.50 сел бы прямо на образец, пока леджер говорит «полоса пуста». Закрыто: запись wantBestOffTargetTgt и дайджест по всей популяции (id · метка · четыре счётчика, сортировка по id) — пере-взятие корпуса стало осознанным актом, переписывающим строку в том же коммите.

З. ОПЕРАТОРСКОЕ ПРЕДЛОЖЕНИЕ: ЧИСЛО ФЛАГОВ ПЕЧАТАЛОСЬ ЧИСЛОМ ПЕРЕДЕЛОК. Пережило весь пакет: обе фикстуры, читающие это предложение, имели Reworked == Flagged == 1. Разведены.

И. ФЛАГ, РАДИ КОТОРОГО ПОСТРОЕН ПУНКТ 2, БЫЛ САМЫМ БЕЗОБИДНЫМ В ПАСПОРТЕ (находка оркестратора). flagReasonSeverity не знал off_target_lang → дефолт 8, ниже length (6). Глава, вернувшаяся не на том языке, показывала «length» как худшую проблему. У функции не было ни одного теста. Закрыто: switch стал картой, а исчерпаемость держит тест, читающий константы FlagReason из исходника через go/ast — список в тесте гнил бы ровно так же, как список в коде, и заверял бы гниль.

К. ВТОРОЙ CALL-SITE classify (находка оркестратора). repairReGate собирал classifyInput руками из тех же полей, что classifyOutput. Поле TargetScripts однажды уже забыли там, починили руками — и посадка показала, что починку не держит ничто. Закрыто устранением: один конструктор classifyInputFor, пин на нём через рефлексию — любое поле, пришедшее нулевым, валит тест. Список полей в тесте не пишется: его обновлял бы тот же, кто забыл обновить конструктор.

Л. ДВЕРЬ 3 ГЕНДЕРНОГО ТЕСТА ОБЕЩАЛА НЕ ТО, ЧТО ДЕРЖИТ (находка оркестратора, подтверждена исполнением). Её комментарий говорил: «впустят mined-строки в базовый банк — покраснею». Не краснеет: внутри ОДНОГО прогона черновая волна покупается ДО ответа классификатора, поэтому никакое правило про банк не положит род на тот провод. Утверждение об отсутствии оставлено как утверждение о ПОРЯДКЕ, а денежный контракт теперь утверждается там, где живёт — на двух материализованных банках: обогащённый несёт mined-строку, базовый её не выбирает.

М. ИНСТРУМЕНТ ТЕРЯЛ СВОЙСТВО «ГОНЯЕТСЯ ЦЕЛИКОМ» (находка оркестратора). Протухший якорь AF-keys-file-reason-covers-all (протух ещё до этого пака, на 8adcb86) возвращал ОШИБКУ ПРОГОНА и клал весь каталог на 33-й записи из 120 — а прогоны через -id продолжали проходить, и никто не видел. Закрыто: протухание стало ПЕРЗАПИСНЫМ вердиктом ROTTED — прогон идёт дальше, выход остаётся ненулевым, запись предъявляется. Якорь починен.

Что я перепроверила САМА, не приняв на слово

  • Три находки оркестратора, где код на вид противоречил заголовку (repair.go передаёт TargetScripts; CheckPlaceholders сканирует весь canon и ловит незакрытый {{; TestUnionStickyNewestWins на вид ловит keep-first) — прогнала собственные посадки. Две подтвердились как непокрытость, одна — нет.
  • UnionSticky (его находка №4) — ОТВЕДЕНА. Четыре независимые посадки красные. Оркестратор проверил свою на чистой копии b8154cd и снял её сам с точным разбором: его «инверсия» (обход новое→старое с keep-first) ПОВЕДЕНЧЕСКИ ЭКВИВАЛЕНТНА оригиналу (обход старое→новое с перезаписью). Третий класс ложной зелени за сутки — посадка, не меняющая поведения, рядом с моими двумя: упавшая сборка, прочитанная как зелень, и обрезанный вывод, прочитанный как ноль. Общее у всех трёх: читатель верит ВЕРДИКТУ, не проверив, что его произвело.
  • Дыра CheckKeys — не поверила отчёту агента: написала тест, увидела его красным на всех трёх воротах, потом чинила.
  • Каждая из 19 новых записей каталога предъявлена красной прогоном. Одна (WB41) вернулась SURVIVED — моя фикстура случайно давала верный ответ и под посадкой (неподписанная строка была Confirmed и сама наполняла набор подписей). Фикстура переписана так, что подпись — единственный возможный источник; предъявлена красной.

⚠ Чего круг НЕ покрыл

  • Причина S6e — совпадение ли это фикстур или у банк-ролей есть второй путь к клиенту помимо clientFor. Названо агентом, не открыто; я закрыла СЛЕДСТВИЕ (пин на карте клиентов), не причину.
  • Сквозной прогон дыры CheckKeys через NewRunner → волна: закрыто на уровне CheckKeys и пре-строенной карты, но что происходит на живом проводе с ключом-пустышкой, никто не гонял.
  • Резюме через смену версии — end-to-end пере-вердикта резюмированного чанка нет ни одного теста; вся аргументация про --resnapshot держится на чтении.
  • Конвенционный путь стадийного промпта — пер-путевой тест гоняет только prompt_override. Маркер внутри вырезаемого комментария проходит по построению, и НАМЕРЕННОСТЬ этого никем не проверена.
  • Два НЕПОДПИСАННЫХ ряда одной поверхности оба рендерятся: «один приказ на термин» держится только когда подпись есть. Наблюдение агента, теста нет ни в ту, ни в другую сторону.
  • precomputeStickyсброс на границе главы и запись переноса, заблокированного спойлером.
  • Сам харнесс tmmutate (отпечаток и восстановление) и единственная запись expect: survives (G-byte-gate) не ревьюились ни одним кругом из трёх.
  • Ракурсы, унаследованные непокрытыми из круга 2 и не открытые снова: $0-проекции на дефектной книге · липкий перенос до редакторского провода сквозным · настоящая латинописьменная цель (target-en.txt в репо нет) · eval/-харнессы вне модуля.
  • F11 остаётся риском дизайна, не чинен: порог экрана калиброван на ОДНОЙ сянься-новелле; на латино-тяжёлом здоровом русском даёт ложный off_target (0.461 с пиньинь-глоссами, 0.077 с shell-командами), а ложный флаг ЭСКАЛИРУЕТ — то есть стоит платного вызова. Оркестратор забрал носителем.
  • Круг 3 не ревьюил мои правки круга 3. Копии агента сняты до них. Четвёртый круг, если он будет, начинается отсюда.

Числа круга

Батарея MAKE_EXIT=0, 0 issues, все пакеты ok (pipeline 571 s под -race), скипы те же. Голден в этом круге не трогали, и TestGoldenDeterminism проходит против него — круг не сдвинул ни одного байта провода. Тесты 1156 → 1173. Каталог 120 → 141; все двадцать одна новая запись предъявлена КРАСНОЙ (WB41со второй попытки, после починки фикстуры, которая случайно давала верный ответ и под посадкой).

КАТАЛОГ ПРОГНАН ЦЕЛИКОМ — впервые, и первый же целый прогон окупил починку инструмента. 141 запись: 136 RED · 0 SURVIVED · 0 NOTHING · 1 записанный survives (G-byte-gate, аргументирован) · 4 ROTTED. Протухли четыре МОИ ЖЕ записи, чьи якоря увезли рефакторы кругов 23: WB5 (сборка classifyInput уехала в конструктор), WB12 (правило дедупа исправлено кругом 2 — запись описывала регрессию, которую я же и починила), WB16 (у валидатора не стало собственного списка), WB21 (банк-роли уехали в gateModels). Под прежним поведением прогон лёг бы на первой из них, и трёх остальных никто бы не увидел — ровно то, что произошло с AF-keys-file-reason-covers-all и держалось незамеченным два пака. Все четыре пере-навешены на нынешние выражения тех же свойств (у WB12 и WB16 заодно переписан why: свойство изменилось, а не только адрес) и предъявлены красными. AF в целом прогоне — RED, то есть починка якоря проверена не на слово.

Файлы

Изменены: internal/pipeline/{disposition,chunkrun,waverun,events,manifest,mining,terminologist,repair,render,runner}.go · internal/membank/{memory,mempostcheck,decisions}.go · internal/terminology/{terminology,classify}.go · internal/miner/miner_emit.go · internal/checks/sanitizer.go · internal/config/{book,pipeline}.go · internal/lang/embedded.go · internal/store/migrate.go · cmd/tmctl/render.go · cmd/tmmutate/mutations.json (92 → 96) · configs/pipeline-{c1,c2,arm-*}.yaml · prompts/zh-ru/*.md (шесть — жанр; classifier.md — третье поле) · example/book.yaml · тесты и голден. Новые: internal/langscreen/{langscreen,langscreen_test}.go · internal/pipeline/{cuttag_test,gender_wire_test,offtarget_corpus_test,volumepanic_test,offtargetflag_test,contourpreflight_test}.go · internal/pipeline/testdata/offtarget-corpus.json · internal/config/{bank_contour_test,genre_retired_test}.go · internal/checks/latinguard_test.go.

Команды приёмки

cd backend && make battery                                     # MAKE_EXIT=0, 0 issues, 19 пакетов ok, 3 скипа
go test ./internal/pipeline/ -run 'Gender' -v                  # производитель рода, три двери доставки
go test ./internal/pipeline/ -run 'OffTargetCorpus|LiveEchoGate|LatinOffTarget|TargetScreen|TwoScreens|ScreenConstants' -v
go test ./internal/langscreen/ -v                              # изолированный модуль экрана
go test ./internal/config/ -run 'BankContour|BankRoleBudgets|Genre' -v
go test ./internal/membank/ -run 'ApprovingATermKeeps|LawBlockGivesOneOrder' -v   # род переживает подпись; один приказ на термин
go test ./internal/pipeline/ -run 'OffTargetCompletionIsFlagged|RunnerHandsTheScreen|ThresholdIsUsed|ContourRefusesAWriteRun|RenderRejectsUnknownPlaceholder' -v
go test ./internal/checks/ -run 'LatinResidueClassIsGated' -v  # вторая половина дыры 46, обе стороны
go test ./internal/pipeline/ -run 'ACrashOverACaughtCeiling|StopLineSaysTheGrant|OneCarriedUnit' -v
cp -a backend /tmp/mut/backend && cd /tmp/mut/backend && GOFLAGS=-buildvcs=false \
  go run ./cmd/tmmutate -root . -id WB1-head-always-end-of-book,WB2-head-keyed-on-the-carry,WB3-bound-border-drops-a-single-carry,WB4-cut-tag-drops-the-embedded-data,WB5-target-screen-never-sees-the-target,WB6-off-target-flag-not-escalatable,WB7-bank-role-exemption-narrows-to-one-role,WB8-latin-residue-runs-on-a-latin-target,WB9-contour-configured-and-inert,WB10-missing-contrast-costs-a-wave,WB11-nil-pack-contour-never-runs,WB12-two-orders-for-one-term,WB13-placeholder-refusal-arrives-after-a-paid-wave
grep -rl '{{genre}}' backend/prompts/ | wc -l                  # 0
grep -rn '^func Test' backend --include=*_test.go | wc -l      # 1143
python3 -c "import json;print(len(json.load(open('backend/cmd/tmmutate/mutations.json'))))"   # 105

04.09 — записка-план вайр-батча «род · экран цели · заголовки инъекций» (промт BACKEND_WIREBATCH_SESSION_PROMPT.md, сессия textmachine-main-7e)

Скоуп — шесть пунктов промта. (1) 210: род производится авто-путём, доказательство сквозным прогоном «произведено → отрендерилось». (2) 113 → 46 в этом порядке: корпус-фикстура и регресс на реальный запас боевого гейта, потом экран цели именованным флагом + вторая половина дыры detectLatinInsertion. (3) 134: единый закон-блок редактора, маркер ⟨проверить⟩ с провода, то же у транслятора. (4) 140: банковый контур в pipeline-c1.yaml, суб-бюджеты ×4.47. (5) 184(а): {{genre}} из шести промптов пары и поле из канона брифа. (6) ДОФИКС чужого пака D39.187 п.4 (две посадки + граница bound() + три числа) и ФЧ-7 строки 197 — ПРОВЕРКОЙ, не стройкой. Инварианты. Не коммичу — дерево на лендинг оркестратору. НЕ двигаю: схему хранилища · manifestVersion · StreamVersion · версию контракта. Новый эмбед-файл не завожу. FlagCJKArtifact не переиспользую (снято D39.93 п.2). Статусы строк и подписная таблица в 134 не трогаются (D39.104 п.1). Семантику переноса слота не трогаю. Текст заголовка редактора не меняю — он байт-идентичен арму AM-noclause пробы 18 (experiments/18-editor-wire-probe.md §0.3). Развилки, объявленные ДО кода. (1) род — производится КЛАССИФИКАТОРОМ (третье поле его ответа), а не терминологом и не третьим проходом: ноль новых вызовов, парсер классификатора позиционный и закрыто-словарный. (2) Второй замок (Confirmed-фильтр рендера рода) — вынесен пингом оркестратору на ратификацию, сам не снимаю. (3) 134 — снимаю РЕНДЕР в Go, internal/lang/data/injection.txt НЕ трогаю: правка данных двигает EmbeddedVersioncutTagmanifest_key → снос unit_resolutions книги ПАРАЛЛЕЛЬНОГО платного прогона платформы. Что НЕ делаю. Чужие зоны platform/ frontend/ eval/ и соседний worktree. Строки 131 · 105(а) · 14 · 119 · 124 · 115 · 160 · 161 · 142. Самопроверка исполнением. Дифф ^func Test пофамильно до/после (удалённых имён 0) · маскированный дифф голдена (только названные версионные оси + ровно две строки диспозиций) · собственные посадки tmmutate ВНЕ шести пунктов на копии дерева · отдельный адверсариальный проход свежим контекстом (модель назову) · отчёт о движении cutTag: tmctl manifest до и после.

Канала к оркестратору нет: адрес в /tmp/textmachine-channel (textmachine-33) в ListAgents отсутствует, промт писан на другой машине — вопросы едут секцией отчёта ниже. Дерево на входе чисто, HEAD 494c4ef; все file:line-якоря промта сверены грепом на этой машине и сходятся. Скоуп — четыре пункта в порядке промта: (1) ФЧ-5, ось МОДЕЛИ: строка прайсится по модели, которую её стадия резолвит СЕЙЧАС (Stage.ResolvedModel); округление вверх при незнании = максимум из цен по ответившей модели, по текущей и — для эскалационных вызовов — по текущему хопу; оговорка «оценка, ошибается вверх, вот чем» в ОБОИХ текстах согласия; обещание точности снимается в status.go (комментарий у RebillUSD) и в шапке reprice.go. (2) Строка 232, остаток «слот»: юнит, который прежний прогон НАЧАЛ (есть строки текущих позиций) и не отгрузил по оси finalStageWave, слота гранта повторно не тратит — дописывается вне гранта, считается отдельно. (3) ФЧ-4 обе половины: rebill_historical_rows в status --json под тем же rebill_basis + basis в тексте отказа --accept-rebill=<usd>; одна формулировка basis для CLI-статуса и текста отказа. (4) ФЧ-1: ровно три названные гарантии — сперва воспроизвести мутацию на копии и увидеть зелень, потом посадка тестом + запись в cmd/tmmutate/mutations.json. Инварианты: направление ошибки — никогда не занизить молча (D39.150) · status и translate — ОДИН вывод · фигура едет с базисом (D39.181 п.1) · ось отгрузки = finalStageWave, не draft и не «любая» · схема хранилища, форма манифеста, версия контракта НЕ трогаются · тесты не подгоняются, заказанная смена поведения объявляется (D39.183). Не делать: строки 160 · 221 · 224 · 226 · 228 · 230 · 246 · 247 · 233 · 229 · 141-остаток · 131 · платный замер · новое поле в кадре finished шва (класс «поле в опубликованном документе» — ратификация оркестратора; счётчик «дописан вне гранта» живёт в отчёте прогона и логе, вопрос — в отчёт) · коммиты. Самопроверка исполнением: дифф ^func Test (база 1083, снимок имён снят) · собственные посадки tmmutate на копии в scratchpad · свежий адверсариальный проход субагентами Fable 5 (число назову) · make battery на копии до и на дереве после.

Итог: четыре пункта состава исполнены, дерево backend/ готово к лендингу, НЕ КОММИЧУ (git diff --cached --name-only → пусто). HEAD на входе 494c4ef; после согласованного с платформой (textmachine-37) git pull --ff-only2a63c37. Входящее (72 файла) не пересекалось ни с одним моим файлом, кроме docs/PROGRESS.md: свою записку сняла редактором, дала git пройти fast-forward, вернула. Индекс не трогала, stash не применяла. Канала к оркестратору нет: textmachine-33 в ListAgents отсутствует, промт писан на другой машине — вопросы секцией ниже. Все file:line-якоря промта сверены грепом здесь и сошлись. Батарея на финальном дереве: cd backend && make batteryMAKE_EXIT=0, golangci-lint 0 issues, ok в 18 пакетах, SKIP: TestMinerFullBookParity, TestHelperEventsRun, TestHelperKillLoop. ⚠ Скипов ТРИ, а не шесть как в базовом прогоне, и это не ослабление: TestCheckerLabelsBaseline/TestCheckerLabelsCandidates/TestK6LabelsBaseline в реальном дереве корпус находят и ИДУТ — go test ./internal/checks/ -run TestCheckerLabelsBaseline -count=1 -v--- PASS, go test ./... -run TestK6LabelsBaseline -count=1 -v--- PASS. Базовый прогон гнался на копии в /tmp, где маркер корня репозитория не находится. Тесты ^func Test: grep -rn '^func Test' backend --include=*_test.go | wc -l1083 → 1105; пофамильный дифф двух снимков (comm -23) — удалённых 0, добавленных 19.

Комплектность против заказа — по четырём пунктам и по таблице разметки.

1. ФЧ-5 — ось МОДЕЛИ. Все ЧЕТЫРЕ обязательства D39.150 п.1.

  • (1) прайс по модели, которую стадия резолвит СЕЙЧАС. internal/pipeline/reprice.go, currentModelFor(stage, escalation): для эскалационного вызова — текущий ResolvedHop, иначе ResolvedModel. Именно РЕЗОЛВЕННЫЙ слот, а не конфигурационный model: — на книге с лейблами это разные модели, и прайсить надо по той, которую прогон вызовет (пин TestTheModelAxisReadsTheRESOLVEDSlotNotTheConfiguredOne, каталожная запись FC5-model-axis-configured-slot). Признак эскалации взят из колонки checkpoints.escalation полем store.CheckpointUsage.Escalation; схема НЕ тронута (git diff --stat -- backend/internal/store/migrate.go → пусто), колонка живёт с v3.
  • (2) округление ВВЕРХ при незнании — формула моя. now = max( cost(токены @ модель, которая ОТВЕТИЛА), cost(токены @ модель, которую стадия резолвит сейчас) ). Довод: количество токенов принадлежит ответившей модели, цена — той, которая ответит; ни одна не смеет опустить число ниже другой. Оба направления проверены исполнением: стадия ушла на модель ×10 — число ×10 (замер приёмки $0.003640 против $0.036400 воспроизведён тестом); стадия ушла на модель ÷10 — число НЕ падает. База порога projectBookUSD считается тем же usd(), поэтому обе половины гейта в одной валюте.
  • (3) оговорка в тексте согласия. projectionBasis (rebill.go): «…an ESTIMATE that errs upward, never below what the answering model would charge for the same tokens where their usage is on file; K of the N unit(s) were bought from a model their stage no longer resolves to…». Едет в ЧЕТЫРЁХ операторских местах: пороговый отказ, его scoped-клауза, отказ по названному потолку, и tmctl status через StatusReport.RebillFigureBasis().
  • (4) обещание точности СНЯТО в ОБОИХ живых местах, названных промтом. git grep -n 'can never quote a different number' -- backend/ → пусто; на входном коммите git grep -n 'can never quote a different number' 2a63c37 -- backend/ | wc -l1 ⚠ (в первой редакции отчёта стояло «3» — число было снято широким грепом на три разных шаблона и приписано этому, узкому; исправлено дофиксом); grep -rn 'NOT projected (like the content axis' backend/internal → пусто. Заменено: шапка reprice.go — «ROUTING IS PROJECTED, AND IT ROUNDS UP»; комментарий RebillUSD в status.go — «what neither of them promises is ACCURACY… an estimate that errs UPWARD where the tokens are known». Третья копия обещания (исторический комментарий у projectStoredMemory) снята попутно.
  • Решила сама, сверх буквы заказа: счётчик RebillProjection.ModelMovedRows и поле rebill_model_moved_rows в status --json. Довод: фигура, часть которой — верхняя оценка через смену модели, без этого числа неотличима от точного пере-прайса, а D39.181 §2.3 требует базиса у опубликованной фигуры. Это ВТОРОЕ новое поле сверх названного промтом одного — вопрос 3.

2. Строка 232, вторая половина — ЗАКРЫТА ТОЛЬКО ПО ОСТАТКУ «СЛОТ».

  • Ось отгрузки — finalStageWave, как велено; не draft и не «любая». Проверена исполнением и на редакторском, и на ЧЕРНОВОМ-ТОЛЬКО конвейере (TestDeliveryIsReadFromTheSHIPPINGWaveOnADraftOnlyPipeline, TestACarriedUnitOnADraftOnlyPipeline).
  • Механизм. Класс unitCarried в volume.go: юнит, у которого есть строка ХОТЯ БЫ ОДНОЙ позиции, исполняемой этим конвейером, но не всех, и который не отгружен по оси. Он допускается ВНЕ гранта, но платит; в отчёте — внутри Delivered и отдельно в Carried. Сравнение с потолком — granted() = Delivered Carried + Reworked, заменило Paid() в ОБОИХ местах (planVolume, rescopeEditWave).
  • И сам перенос ОГРАНИЧЕН ГРАНТОМ — не больше MaxUnits перенесённых за прогон, в порядке книги. Без этой границы потолок переставал быть потолком: прогон без --max-units, начерновивший всю книгу и умерший до редакторской волны, отдавал следующей покупке ВСЕ свои юниты. Замерено на фикстуре: грант 1 оплачивал 5 юнитов и 5 вызовов провайдера, а поскольку в остатке не оставалось ничего, прогон не отчитывался вовсе. Найдено адверсариальным проходом по МОЕЙ ЖЕ работе. Принцип границы, а не число: покупка на N может дописать столько же прерванных юнитов, сколько начинает новых, — работа прогона остаётся пропорциональна гранту. Не влезшее держится как LeftFresh («никогда не доставлено»), потому что это ровно оно.
  • bound() теперь истинен и когда Carried > 0, а не только когда что-то удержано: прогон, дописавший юниты вне гранта, обязан это СКАЗАТЬ, иначе молчание приходится ровно на случай с наибольшим расхождением.
  • Решила сама (промт отдал): где вычитается потраченный слот — нигде: он НЕ БЕРЁТСЯ. Как переживает рестарт — носитель «юнит начат» — его же строки chunk_status по текущим позициям (unitStarted/unitPositionsOnFile, одно перечисление с unitFullyRecorded, чтобы они не разошлись в понимании «позиции»); схемы не нужно. Частично двинутый юнит — carried, дописываются только недостающие позиции.
  • Замер строки исправлен: было «4 купленных юнита → 2 главы», стало 4 → 4 (TestAUnitInterruptedBetweenWavesTakesNoSecondSlot: Delivered=4 Carried=2 LeftFresh=1, ровно 6 вызовов во второй покупке).
  • Семантика --max-units изменена и объявлена во всех трёх операторских местах (cmd/tmctl/invocation.go, Runner.MaxUnits, backend/README.md): грант считает юниты, которые прогон БЕРЁТ СЛОТОМ — новые и пере-делываемые; перенесённые названы в строке стопа и в логе (finished_from_an_earlier_grant). ⚠ Тексты НЕ утверждают, что «слот за юнит был взят прежним прогоном»: движок этого не знает (прежний прогон мог идти без потолка), и первая редакция текстов это утверждала — снято.
  • ОСТАТКИ, которые пак НЕ закрывает — названы в докстринге deliveredUnits и здесь:
    1. «первая редакторская стадия» (остаток, который промт велел назвать): конвейер, получающий ПЕРВУЮ редакторскую стадию, двигает отгружающую волну с draft на edit, и уже прочитанные юниты репортятся свежими. Закрытие требует записи о том, ЧЕМ БЫЛА отгружающая волна.
    2. Прерванная ПЕРЕ-ДЕЛКА — новый остаток, найденный этим паком. Отгруженный юнит, чья пере-делка оборвана между волнами, имеет строку в КАЖДОЙ позиции, снова классифицируется unitRework и снова берёт слот. Отличить его от обычного банк-онли сдвига (черновик free, редактор пере-оплачивается — определение rework) можно только записью «какой прогон купил какую строку». Строку 232 закрываю только по остатку «слот», как и велено.

3. ФЧ-4 — ОБЕ половины, фигура едет с базисом (D39.181 п.1).

  • (а) HistoricalRows больше не теряется на границе status.go: rebillOutcome возвращает проекцию ЦЕЛИКОМ (под none/failed — нулевую структуру, так что новое поле не может пережить «неизвестный» ответ, забытое в одной ветке), в StatusReportrebill_historical_rows и rebill_model_moved_rows под тем же rebill_basis.
  • (б) отказ по названному потолку --accept-rebill=<usd> несёт projectionBasis(proj) — базис ТОЙ ЖЕ run-scoped проекции, чьё число печатает.
  • Сверх заказа, по тому же правилу «каждая цифра предложения — из его проекции»: scoped-клауза ПОРОГОВОГО отказа печатала число этого прогона рядом с книжным базисом; теперь несёт свой (TestTheScopedClauseOfTheRefusalCarriesItsOwnBasis). Дефект был и до пака.
  • Один вывод на два канала: StatusReport.RebillFigureBasis() → строка RE-PAYMENT в tmctl status; TestABilledDecodeRowIsDisclosedAsOldMoneyEndToEnd сверяет, что проекция, --json, CLI и ОБА текста отказа называют одну строку раскрытия.
  • Решила сама (промт отдал: имя поля · форма basis · что печатать при HistoricalRows=0). Имяrebill_historical_rows, в форме соседей по префиксу rebill_*. Форма basisНЕ второе поле-строка рядом с числом, а одна формулировка projectionBasis, которую метод RebillFigureBasis() переиспользует для CLI: существующий rebill_basis остаётся КАЧЕСТВЕННОЙ осью (pending/stored/none/failed), а новые счётчики — количественной, и словами их описывает один текст, чтобы гейт и статус не разошлись формулировкой. При нуле — печатается ноль, а не пропуск поля: omitempty здесь тот же дефект, ради которого его сняли с rebill_units/rebill_usd — отсутствие поля неотличимо от «свободно». Ноль под pending значит «всё пере-оценено», под failed — «не считалось»; различает их rebill_basis. В операторском тексте при нуле клауза просто не печатается: предложение не должно нести оговорку, у которой нет предмета.

4. ФЧ-1 — ровно три названные гарантии, по каждой все ТРИ шага.

  • Шаг 1 — воспроизвести на копии ДО пака. cp -a backend /tmp/.../mut0/backend, go run ./cmd/tmmutate -root . -catalog prepack_mutations.jsonвсе пять посадок SURVIVED: фильтр по книге в ОБОИХ пакетах, ключ ячейки без chunk_idx в ОБЕИХ формах, снятие пометки «не пере-оценена». ⇒ гарантии (2) и (3), принятые приёмкой СО СЛОВ линзы, подтверждены исполнением; ни одна не оказалась уже прибитой.
  • Шаг 2 — посадки тестом. (1) TestCheckpointUsageForBookIsScopedToTheBook (две книги в одной БД, ОДНА позиция) + TestAnotherBooksMoneyNeverEntersTheConsentNumber. (2) TestEveryChunkOfAChapterIsRePricedFromItsOwnCalls — глава из нескольких чанков РАЗНОЙ стоимости: единственная форма, в которой пул ячейки виден (во всех прежних фикстурах глава = один чанк, потому мутация и переживала). (3) TestABilledDecodeRowIsDisclosedAsOldMoneyEndToEnd — продовый путь до --json, CLI и обоих отказов.
  • Шаг 3 — каталог. cmd/tmmutate/mutations.json: 73 → 92. Четыре записи FC1-* на три гарантии (фильтр по книге пинится в двух пакетах) плюс две FC5-* на несущие свойства, которые пак СОЗДАЛ (граница переноса и резолвенный слот) — их я завела по той же логике, по которой каталог существует. Денежный путь в каталоге: греп промта считает СТРОКИ — git show 2a63c37:backend/cmd/tmmutate/mutations.json | grep -c 'reprice.go\|rebill.go\|volume.go\|ledger.go'0, тот же греп по дереву → 17; различных ФАЙЛОВ денежного пути — 0 → 4 (reprice.go, rebill.go, volume.go, store/ledger.go). ⚠ В первой редакции стояло «стало 5 файлов» — такого числа не даёт ни одно прочтение; исправлено дофиксом. Прогон всех шести на свежей копии: 6 RED, «0 unexpected outcome(s)», exit 0.
  • Четвёртого одноразового харнесса не писала; tmmutate гоняла только на копиях в scratchpad.
  • Решила сама (промт отдал: форма посадок · уровень теста · текст why). Форма — ломать ровно то утверждение, которое гарантия держит, минимальной правкой, и обязательно КОМПИЛИРУЮЩЕЙСЯ: рецепт, оставляющий переменную неиспользованной, даёт tmmutate вердикт «ничего не выполнялось», а не «красное», — на этом я поймала два своих же докстринга и переписала их. Уровень — по тому, где живёт защита, а не где живёт правка: фильтр по книге пинится и в store, и в pipeline (мутация пережила обе батареи по отдельности, значит одной мало); ключ ячейки — только pipeline, дефект в newRepricer; пометка «строка не пере-оценена» — pipeline, и именно ПРОДОВЫМ путём, потому что промт называл её не ловящейся на нём. Текст why — называет СВОЙСТВО и причину, по которой его не видно («во всех прежних фикстурах глава = один чанк»), а не описание правки: why читают в тот момент, когда мутация выжила и надо понять, что именно перестало охраняться.

Правки СУЩЕСТВУЮЩИХ тестов — объявляются (D39.183).

  • TestAFlaggedMemberWithNoEditRowIsNotFree (volume_test.go): описывал «юнит без edit-строки ОБЯЗАН потратить грант» — поведение, которое заказывает пункт 2. Гарантия «не FREE, платит и отчитывается как платящий» СОХРАНЕНА; гарантия «берёт слот» уехала в противоположную. Фикстура расширена до 4 глав; после введения границы переноса ожидание — Delivered=2 Carried=1 LeftFresh=2.
  • TestAnAnnouncedButFLAGGEDUnitIsStillNewBook, TestAUnitWhoseEDITFlaggedIsStillNewBook (volumedelivery_test.go): флагнутый юнит после добавления стадии теперь carried. Гарантии «анонс ≠ текст» и «судить по ОТГРУЖАЮЩЕЙ строке» сохранены; фикстуры расширены до 3 глав, сигнатуры названных мутаций пере-выведены. ⚠ Рецепты мутаций в их докстрингах были НЕИСПОЛНИМЫ (правка на месте вызова оставляла shipStages неиспользованным, пакет переставал собираться, и tmmutate дал бы NOTHING вместо RED) — переписаны на правку тела unitShipped.
  • Смена сигнатур (repriceCheckpoint/usd — третий возврат moved; rebillOutcome — проекция целиком): TestRepriceCheckpointFallsBackToTheBilledAmount (таблица расширена до 11 случаев), TestRepricerCountsOnlyTheCurrentGenerationOfCheckpoints (+4 строки), TestAFailedBasisNeverCarriesAFigure (сравнивает всю структуру с нулевой — стал строже), TestRebillConsentCapBelowProjectionRefuses (+утверждение про базис), TestCheckpointsOfOneGenerationSumToTheRowsCost (адаптирован под третий возврат usd(); ослабления нет, правка механическая — ⚠ в первой редакции отчёта имя пропущено, дописано дофиксом), reprice_model_test.go и render_test.go (формулировка оговорки: «were answered by» → «were bought from», см. ниже).
  • TestStatusPricesTheDriftWithTheGatesOwnNumber — тронут ТОЛЬКО комментарий, цитировавший снятое обещание. Тест не менялся.
  • Удалённых имён — 0.

Мандат самопроверки — три артефакта.

  1. Дифф ^func Test исполнением: 1083 → 1102, удалённых 0, добавленных 19.
  2. Собственные адверсариальные посадки ВНЕ трёх гарантий: каталоги own_mutations.json (26), round2_mut.json (5), round3_mut.json (2), draftonly_mut.json (2) — 35 посадок, tmmutate на копиях. Итог: все RED. ⚠ В первом круге ДВЕ пережили, и это находки: X21 (rescopeEditWave сравнивал грант через Paid(), то есть считал перенесённый юнит за слот и отказал бы в свободном) и X22 (строка стадии, которой конвейер больше не исполняет, засчитывалась как «юнит начат»). Обе прибиты (TestTheRePlanCountsSlotsNotCarriedUnits, TestRowsOfARetiredStageAreNotAStart) и во втором круге RED.
  3. Проход по СВОЕЙ готовой работе свежим контекстом. Воркфлоу из семи линз (направление ошибки · раскрытие на новой границе · слот и черновой конвейер · вывод членства usd() · правда текста · качество тестов · скоуп и заказ), каждая находка судится тремя независимыми опровергателями (корректность · воспроизведение · сверка с промтом), большинство решает. Модели: линза качества тестов — Fable 5, остальные — Opus 5 (ограничение владельца на число Fable-агентов соблюдено: один). Числа прохода: 7 линз, 27 находок (2 HIGH · 12 MED · 13 LOW), 42 вердикта верификаторов, 46 агентов. ⚠ Верификаторов «подтверждено» — НОЛЬ, и читать это надо точно: фаза верификации шла по дереву, где все 27 находок были уже исправлены, то есть опровергатели подтверждали ПРАВКИ, а не отсутствие дефектов. Каждая находка ниже воспроизведена или прочитана мной по коду до правки. Находки и диспозиции (все ИСПРАВЛЕНЫ, каждая с посадкой):
    • [HIGH] перенос без границы обнулял потолок — грант 1 оплачивал 5 юнитов, и прогон об этом молчал. Введена граница Carried ≤ MaxUnits + bound() по Carried; посадки FC5-carry-unbounded и FC7-volume-stop-silent-outside-grant (в первой редакции вторая называлась разведочным именем Y2-silent-when-nothing-left, которого в каталоге нет — переименовано дофиксом, Б7).
    • [MED] reconcile мог вывести Delivered ниже Carriedgranted() уходил в минус, строка стопа говорила «0 NEW unit(s) delivered (1 of the new ones had been started…)», предложение, которое не может быть истинным. Все ветви теперь держат вложенность; посадки FC7-reconcile-free-branch и FC6-reconcile-fresh-branch (в первой редакции стояло разведочное Y3, которого в каталоге нет — переименовано дофиксом, Б7).
    • [MED] операторские тексты утверждали «слот за юнит был взят прежним прогоном» — движок этого не знает. Снято во всех трёх местах.
    • [MED] ось модели не была прибита на РЕЗОЛВЕННОМ слоте — чтение st.Model вместо st.ResolvedModel переживало весь пакет. Пин + каталожная запись FC5-model-axis-configured-slot.
    • [MED] $0-строка без usage под сдвинутой стадией публиковалась как $0 без оговорки. Теперь помечается «не удалось пере-оценить»; посадка FC7-zero-usage-row-silent-after-a-move (в первой редакции — разведочное Z2).
    • [MED] scoped-клауза порогового отказа шла без своего базиса (дефект был и до пака) — исправлено, посадка FC7-scoped-clause-without-basis (в первой редакции — разведочное X29).
    • [LOW] ветка отката (overshoot) причисляла строку к «пере-прайсенным по сдвинутой модели», хотя цитирует БИЛЛЕННУЮ сумму, не прайсенную ни по одной сегодняшней таблице. moved там снят; посадка FC7-overshoot-claims-a-model-move (в первой редакции — разведочное Y4).
    • [LOW] moved считается против ModelRequested, а пять текстов говорили «модель, которая ОТВЕТИЛА» — на провайдере, канонизирующем слаг (gpt-5-mini → дата), это разные вещи. Код верен (пере-прогон запросит модель стадии), тексты приведены к нему.
    • [LOW] комментарий про zeroRow утверждал, что хвост $0-вызовов — ОДНО поколение. Это неверно: $0-стадия оставляет cost_usd == 0 после каждого прогона, поколения неразличимы, и число может быть кратным. Направление при этом ратифицированное (вверх), и оговорка «errs upward» его покрывает; ложное утверждение из комментария снято, ограничение названо вслух.
    • [LOW] комментарий про redrive утверждал, что пере-атакованный юнит «начинается заново». Неверно: ResetChunkStages удаляет только FLAGGED и SKIPPED стадии, черновая ok-строка остаётся, и юнит остаётся carried. Комментарий приведён к коду.
    • [LOW] доки кадра finished (runevents.VolumeLedger) отправляли читателя к полю Free за объяснением «почему юнитов больше, чем грант», хотя теперь причина может быть и в Delivered. Тексты исправлены; поля на провод НЕ добавлено — вопрос 1. В runevents/ изменены ТОЛЬКО комментарии (проверено: дифф без строк кода), StreamVersion не тронут.
    • [LOW] докстринг CheckpointUsageForBook ссылался на несуществующий id каталога FC1-book-filter (в каталоге две записи, -store и -pipeline); tmmutate -id матчит точно, и следующая сессия получила бы «ничего не выбрано». Исправлено.
    • [LOW] комментарий у RebillHistoricalRows называл платформу потребителем поля — её аллоулист не берёт ни одного rebill_*. Формулировка приведена к факту: потребитель — операторская оснастка, читающая документ; платформа поле игнорирует.
    • [LOW] несколько комментариев рассказывали ИСТОРИЮ починки («used to», «went stale once already», «is how four bought units became two chapters») вместо описания кода — закон владельца. Переписаны; провенанс оставлен только в докстрингах ТЕСТОВ, где он в зоне принят.
    • [LOW] «первая половина» текста согласия обещала «never below…» без оговорки про строки, которые пере-оценить не удалось: они как раз могут стоять НИЖЕ сегодняшней таблицы. Добавлено «where their usage is on file» и «may sit below today's table».

Три оси ревью, названные промтом уязвимыми именно в этом паке — по каждой предъявляю.

  1. Направление ошибки. Двойной счёт искала специально: порог сравнивает базу и сумму, посчитанные ОДНИМ usd() (тест сверяет projected_book_usd, а не только сумму), максимум из двух цен берётся РОВНО один раз на вызов, добавка денег банк-ролей входит в опубликованную проекцию и НЕ входит в базу порога — как ратифицировано. Перелёт порога проверен с обеих сторон: число выросло там, где занижало, и не упало там, где стадия ушла на дешёвую модель. Одну форму двойного счёта ревью всё же нашло — кратность оценки $0-строки; направление у неё безопасное (завышение), ограничение названо вслух и в коде, и в секции «не проверено».
  2. HistoricalRows на новой границе. Не теряется и не удваивается: единственный инкремент на строку, rebillOutcome отдаёт проекцию целиком, под «неизвестно» — нулевую структуру. Текст отказа и --json называют ОДНО число с ОДНИМ базисом — это утверждает тест, сравнивающий подстроку RebillFigureBasis() внутри текста отказа, а не два независимых ожидания.
  3. Слот гранта на черновом-только конвейере. Проверено исполнением, а не рассуждением: TestACarriedUnitOnADraftOnlyPipeline — ось не выродилась в «никогда ничего не отгружено» (юнит, начатый и не отгруженный, опознаётся и дописывается), и не выродилась в обратную сторону (уже отгруженные не пере-продаются — TestDeliveryIsReadFromTheSHIPPINGWaveOnADraftOnlyPipeline).

Что НЕ удалось и что НЕ проверено.

  • Остаток «первая редакторская стадия» — вне скоупа, требует носителя прошлой отгружающей волны (схема).
  • Остаток «прерванная пере-делка» — найден этим паком, требует записи «какой прогон купил какую строку» (схема).
  • Кратность оценки $0-строки: книга, у которой $0-стадия пере-куплена N раз, а потом уведена на платную модель, получает оценку, кратную N. Направление безопасное (завышение) и объявлено в тексте согласия, но точным его не сделать без маркера поколения на checkpoints — та же схемная развилка, что в докстринге usd().
  • Юнит, начатый НЕОГРАНИЧЕННЫМ прогоном, слота в следующем ограниченном не берёт (но перенос ограничен грантом). Замерено тестом, на живой книге не проверялось.
  • Взаимодействие переноса с ДЕНЕЖНЫМ потолком на длинном хвосте начатых юнитов не замерено: по построению объёмный потолок их не считает, держит денежный.
  • Живой прогон с платными вызовами не делался — промт его не заказывал. Вендор-сверок нет: пак не трогает слаги моделей.

⚠ Якоря в ЧУЖИХ доках, уехавшие ИЗ-ЗА пака — править не могу, зона не моя; вот готовый список с новыми номерами (python3 docs/scripts/counts.py --lint; все шесть были ЦЕЛЫ на HEAD 2a63c37, проверено git show HEAD:<файл> | sed -n '<N>p'):

док:строка якорь был цель сейчас
docs/architecture/15-money-path.md:18 store/ledger.go:381 «SpentUSD reports (committed, reserved)» :392
docs/architecture/15-money-path.md:24 pipeline/status.go:290 «book_ceiling_usd,omitempty» :311
docs/architecture/15-money-path.md:24 pipeline/status.go:788 «100 * (committed + reserved)» :811
docs/PROGRESS.md:179 (тело строки 232) pipeline/status.go:866 «IT IS NO LONGER THE READ PATH'S FIRST ANSWER» :901
docs/archive/prompts/BACKEND_CONSENT_SESSION_PROMPT_2026-09-02.md (строка 52 на момент выдачи; в архиве номера сдвинул баннер исхода) pipeline/status.go:217 «can never quote a different number» снят по заказу (ФЧ-5 п.4)
docs/archive/prompts/BACKEND_CONSENT_SESSION_PROMPT_2026-09-02.md (строка 54 на момент выдачи) pipeline/reprice.go:24 «NOT projected (like the content axis» снят по заказу (ФЧ-5 п.4)

Первые четыре — сдвиг номеров от моих вставок; последние два промт заякорил на тексте, который сам же велел снять, поэтому их «поломка» и есть признак исполнения.

Про остальные 12 я сперва написала здесь «все в docs/experiments/**, пришли с полигонным мержем» — это было неверно, и поправлено разбором с платформенной сессией. Перечисляю по владению; ⚠ общее число гейта — величина ПОДВИЖНАЯ, обе смены правят дерево параллельно: на момент того разбора python3 docs/scripts/counts.py --lint печатал 18, на момент сдачи дофикса — 20 (в отчёте пака стояло «все 18 строк», и это было верно только для того часа). Разбивка по владению взята с той, 18-строчной выдачи:

  • 4 — платформенной сессии (textmachine-37): docs/PROGRESS.md:19, docs/archive/prompts/PLATFORM_P13_SESSION_PROMPT_2026-09-02.md (строка 286 на момент выдачи) и docs/archive/prompts/BACKEND_CONSENT_SESSION_PROMPT_2026-09-02.md (строка 227 на момент выдачи) целятся в одну снятую ею строку рантбука platform/deploy/README.md:213 «сначала платформа, потом движок»; плюс docs/archive/prompts/PLATFORM_P13_SESSION_PROMPT_2026-09-02.md (строка 166 на момент выдачи) на уехавший Quarantine. ⚠ Третий из них живёт В МОЁМ промте (это его -оговорка о том, что совет рантбука опасен), но сломан не мной — целью владеет платформа.
  • 8 — полигонных, пришли с мержем 2a63c37: семь в docs/experiments/** и один в теле бэклога — docs/PROGRESS.md:190 на eval/conformance.py:48.
  • ⚠ Якорь в docs/experiments/23-editor-tier.md:6196 целится в строку 679 этого журнала, которой в нём нет: он был мёртв и до пака (тогда в файле было 472 строки), а мои вставки лишь меняют общее число, которым гейт объясняет смерть. ⚠ Записан здесь СЛОВАМИ, без токена «путь:номер» в обратных кавычках: гейт читает такой токен как якорь, и первая редакция этой строки сама добавила себе двадцатую поломку.

Урок, который стоит записи: первую версию этого абзаца я построила на подсчёте, не перечислив предмет, — тот же класс, что и мои прошлые ошибки «вывести отсутствие из счёта». Счёт по подстроке пути (grep -c 'platform/') тоже не есть счёт по владению: у платформы один из четырёх якорей целится ОТНОСИТЕЛЬНЫМ путём и в такой счёт не попадал.

Вопросы, вынесенные владельцу, и его слово (03.09) — записываю, чтобы решения не пере-открывались.

  1. Поле carried в кадре finished шва (runevents.VolumeLedger). Спрошено: добавлять ли число «сколько глав дописано сверх гранта», ведь delivered теперь может превышать max_units. Цена вопроса названа: это класс «новое поле в опубликованном документе» — ратификация оркестратора плюс минорный бамп StreamVersion, а промт запретил двигать контракт; платформа кадр Volume сегодня не декодирует вовсе (platform/internal/ingest/events.go: Finished{Outcome}), потребителя у факта нет. РЕШЕНИЕ ВЛАДЕЛЬЦА: оставить как есть, поле не добавлять. Исполнено: поля нет, объяснение живёт словами в докстрингах Delivered и Free того же кадра.
  2. Семантика «юнит, начатый прогоном БЕЗ объёмного потолка, слота в следующей покупке не берёт; перенос ограничен размером гранта». Альтернативы названы: тратить на такие юниты купленное (тогда покупатель платит за главу дважды — ровно вред строки 232) либо завести схемный носитель «какая покупка оплатила какую строку». СЛОВО ВЛАДЕЛЬЦА: вынести оркестратору, решение отложено — «подумаем на этот счёт». ⇒ пункт остаётся ОТКРЫТЫМ вопросом к приёмке; в коде сейчас первый вариант, ограниченный грантом.
  3. rebill_model_moved_rows — второе новое поле status --json сверх названного промтом одного; говорит, какая часть суммы завышена из-за смены модели стадии. Аддитивно, платформой игнорируется (её аллоулист не берёт ни одного rebill_*); без него человекочитаемая строка и текст отказа перестают говорить дословно одно и то же. РЕШЕНИЕ ВЛАДЕЛЬЦА: оставить.
  4. Ошибок в промте не нашла.

03.09 — ДОФИКС по приёмке №22 (наряд docs/archive/prompts/BACKEND_DOFIX_2026-09-03.md, сессия textmachine-77)

Состояние git на входе в дофикс — важнее прочего, потому что наряд писан по другому. Наряд говорит «в индексе лежит незакоммиченная работа двух смен». К моменту исполнения владелец уже закоммитил её в ЛОКАЛЬНЫЙ e85295d «temp», а origin/main был обновлён ПРИНУДИТЕЛЬНО на ea54355, в историю которого temp не входит (git merge-base --is-ancestor e85295d origin/main → нет). По слову владельца я откатил temp и подтянул наряды двумя командами: git reset --mixed 2a63c37, затем git merge --ff-only origin/main (перемотка — ea54355 растёт из того же 2a63c37). Перед этим поставил метку temp-backup-e85295d, чтобы коммит с работой обеих смен нельзя было потерять; снимать её до лендинга не надо. Целостность проверена, а не предположена: изменённые файлы совпали с temp бит-в-бит (сравнение хешей двух диффов), пять добавленных файлов снова стали неотслеживаемыми и лежат на диске побайтно как в коммите (git hash-object против git rev-parse e85295d:<файл>). В дереве НА МОМЕНТ ОТКАТА было 44 файла: 22 мои, 21 платформы, один общий журнал; дальше число растёт у обеих смен по мере работы. Индекс пуст, не коммичу.

Батарея после дофикса: cd backend && make batteryMAKE_EXIT=0, golangci-lint 0 issues, ok в 18 пакетах, SKIP: TestMinerFullBookParity, TestHelperEventsRun, TestHelperKillLoop. Тесты ^func Test: grep -rn '^func Test' backend --include=*_test.go | wc -l1083 → 1105 (пак довёл до 1102, дофикс и правки по проверяющему добавили остальное), удалённых 0 (comm -23 по снимкам имён). Каталог cmd/tmmutate/mutations.json: 73 → 92 (python3 -c "import json;print(len(json.load(open('backend/cmd/tmmutate/mutations.json'))))"), прирост 19 записей: паком 6 (FC1×4 — три названные гарантии, FC5×2 — свойства, которые пак создал), дофиксом и разбором его проверки 13 (FC6×4, FC7×5, FC8×3). ⚠ В первой редакции этой строки стояло «18 заведено дофиксом и проверкой», а перечень в скобке давал 14 и не называл FC1 — число одной величины под именем другой, тот же класс, что чинит Б8. Команда: python3 -c "import json;from collections import Counter;d=json.load(open('backend/cmd/tmmutate/mutations.json'));print(Counter(m['id'].split('-')[0] for m in d if m['id'][:3] in ('FC1','FC5','FC6','FC7','FC8')))".

По каждому пункту Б1Б9.

Б1 — стоп-строка и лог лгали в случае, который пак создал. ЗАКРЫТО. Воспроизвёл сам, до правки: VolumeStop{MaxUnits:2, Delivered:2, Carried:2}Left()=0 granted()=0 Paid()=2, и предложение печатало разом «not on money and not at the end of the book» и «Still in the book: 0 unit(s) NEVER delivered». Правка: у String() теперь ДВА открытия по Left(). Грант придержал работу → прежний текст. Книга кончилась → «reached the END of the book under a VOLUME ceiling (--max-units N), which held nothing back», и хвост «Nothing is left in the book» вместо перечисления нулей. Смешанный случай отдельного текста не требует: это первая ветка с уже существующей клаузой про перенесённые. Тот же развилкой пошёл лог waverun.go (сообщение выбирается тем же предикатом), а протухший комментарий у scope.bound() пере-написан на то, что код делает: «set when the grant held work back OR when the run did work outside it». Пин: TestARunThatWorkedOutsideItsGrantSaysSo дополнен — требует и «reached the END of the book», и «Nothing is left in the book», и ЗАПРЕЩАЕТ «not at the end of the book».

Б2 — ратифицированный контракт кадра finished.volume стал ложным. ЗАКРЫТО, поля НЕ добавлял. Утверждение «present only when a volume grant actually held work back» снято во всех ЧЕТЫРЁХ местах: runevents.go (объявление поля и абзац «its PRESENCE is the boolean»), events.go (volumeLedger), bookrun.go (BookResult.Volume). Проверка: grep -rn 'only when the grant actually held something back\|present only when a volume grant actually held\|nil when no grant held anything back\|rather than because the book ended' backend/internal → пусто. Новая формулировка говорит, что присутствие значит «грант был в силе и прогону есть что о нём сказать», и что различают два случая left_fresh/left_reworkоба ноля значат «книга кончилась». Там же прямо сказано, что счётчика перенесённых на проводе НЕТ и почему: владелец 03.09 сказал «оставить как есть». Ратификационная ссылка сохранена с оговоркой, что правило присутствия расширилось вместе со строкой 232.

Б3 — три свойства не были прибиты. ЗАКРЫТО, каждое воспроизведено и посажено. Сначала воспроизвёл все три на копии — все три SURVIVED, как и писала приёмка. После правки те же три посадки на свежей копии → все три RED.

  • (а) ветка unitFresh в reconcile: новый TestReconcileKeepsContainmentOnTheFreshBranch. ⚠ Состояние в нём СКОНСТРУИРОВАНО, а не наблюдено, и это сказано в докстринге: Delivered == Carried с исходом класса unitFresh не даёт сегодня ни одна фикстура. Утверждаю инвариант всё равно, потому что код заявляет его для КАЖДОЙ ветки.
  • (б) отказ по названному потолку: TestTheScopedClauseOfTheRefusalCarriesItsOwnBasis дополнен половиной про --accept-rebill=<usd> — требует «1 of the 1» и запрещает «2 of the 2».
  • (в) оговорка про смену модели при нуле: TestProjectionBasisNamesWhatTheAmountIsMadeOf получил отрицательный пин, симметричный тому, что был у близнеца про старые деньги. Записи каталога: FC6-reconcile-fresh-branch, FC6-capped-refusal-borrows-book-basis, FC6-model-caveat-printed-at-zero.

Б4 — докстринг classifyUnits не пере-считан. ЗАКРЫТО. «three things this run can do to it» → «four»; проверено, что членов unitClass действительно четыре (sed -n '/^const (/,/^)/p' … | grep -c '^\tunit' → 4).

Б5 — пример в README.md:73 противоречил новой семантике. ЗАКРЫТО. «оплатить не больше 10 выходных юнитов» → «не больше 10 выходных юнитов возьмут слот», в согласии с телом README:11.

Б6 — шов store → репрайсер прибит с одной стороны. ВЗЯЛ, хотя пункт «по желанию». Довод: мой же аргумент по фильтру книги («мутация пережила обе батареи по отдельности, значит одной мало») применим и здесь, и отказ от него был бы непоследовательностью, а не решением. Новый TestCheckpointUsageCarriesTheEscalationFlag в internal/store + запись FC6-escalation-flag-store; подмена c.escalation на 0 теперь краснеет и в store-пакете.

Б7 — отчёт ссылался на ПЯТЬ несуществующих посадок как на живые гейты. ЗАКРЫТО заведением, а не снятием ссылок. Проверил каждую из пяти на копии: все пять ловятся существующими тестами — то есть свойства охраняются, но каталог их не помнил, а отчёт называл гейтами. Развязка честная только одна: сделать их настоящими записями. Заведены FC7-volume-stop-silent-outside-grant, FC7-reconcile-free-branch, FC7-zero-usage-row-silent-after-a-move, FC7-scoped-clause-without-basis, FC7-overshoot-claims-a-model-move; все пять пере-посажены → RED.

Б8 — четыре числа не печатались командами, которые отчёт для них называл. ЗАКРЫТО, каждое пере-считано.

  • «денежного пути стало 5 файлов» — такого числа не даёт ни одно прочтение. Правда: греп промта считает СТРОКИ, 0 → 17; различных ФАЙЛОВ денежного пути 0 → 4. Обе команды вписаны рядом с числами.
  • «на входе 3 попадания» у грепа про снятое обещание — правда 1: git grep -n 'can never quote a different number' 2a63c37 -- backend/ | wc -l → 1. Тройка была снята широким грепом на ТРИ разных шаблона и приписана этому, узкому. Тот же класс, что и мои прошлые ошибки со счётом: число из одной команды под именем другой.
  • «все 18 строк» линта — на момент сдачи дофикса гейт печатает 20 (python3 docs/scripts/counts.py --lint). Число ПОДВИЖНОЕ: параллельная платформенная смена правит свои файлы, и её якоря уходят и возвращаются. В отчёт пака вписана оговорка об этом.
  • «в файле 485 строк» — сейчас 572 (wc -l < docs/PROGRESS.md); число снималось до того, как отчёт дорос, и с каждой вставкой меняется. Формулировка в отчёте пака переписана так, чтобы не зависеть от него.
  • Отчёт пака сам добавлял себе поломку гейта: строка таблицы называла чужой мёртвый якорь ТОКЕНОМ «путь-двоеточие-номер» в обратных кавычках, и гейт читал её как якорь ЭТОГО журнала. Переписана словами. ⚠ И первая редакция этого самого пункта наступила на то же место второй раз — объясняя поломку, она снова процитировала токен и снова его создала. Теперь ни одна строка обеих моих записей токена не содержит; проверка — грепом по выдаче гейта на строки этого журнала в моих секциях, пусто.

Б9 — неполнота самообъявления по D39.183. ЗАКРЫТО. TestCheckpointsOfOneGenerationSumToTheRowsCost дописан в блок самообъявления: адаптирован под третий возврат usd(), ослабления нет, правка механическая.

Б10 — к сведению, не заказ; называю, чтобы не умерло молча.

  • Подсказка в докстринге Delivered ключуется на delivered > max_units, а в форме «весь остаток перенесён» delivered == max_units — подсказка не срабатывает, и разложить кадр читателю нечем. Связано с отложенным вопросом владельца о семантике переноса; чинится вместе с ним.
  • В перенос попадает и юнит, который ФЛАГНУЛСЯ и текста не отдал: он «начат и не отгружен», значит следующая покупка снова платит за его пере-атаку вне гранта. Цикл из трёх последовательных покупок не гонял никто — ни приёмка, ни я. Вход в решение владельца, не дефект.

Проверка дофикса свежим контекстом — один агент Fable 5, ограничение владельца соблюдено. Он прочитал исходный промт, наряд, оба моих отчёта и весь дифф, посадил 26 своих мутаций и пере-гнал батарею на копиях. Из его семи находок три взяты в работу и исправлены, четыре названы ниже как известные пробелы:

  • [HIGH] $0-вызов ВНУТРИ платного поколения выпадал из обхода — и уносил с собой сегодняшнюю цену. Форма: черновая стадия на локальной $0-модели с ПЛАТНЫМ escalate_to; стоимость строки объясняет один хоп, поэтому обход останавливался и бесплатный primary терялся, а после сдвига стадии на платную модель число согласия выходило вдвое ниже реальной пере-покупки, БЕЗ оговорки. Воспроизвёл сам на юнит-уровне до правки: usd=0.010000 fromHistory=false moved=false при пере-покупке 0.03. Правило переписано: вызов, стоивший ноль, никогда не останавливает обход и никогда не переполняет счёт — он берётся всегда, а обход стоит на первом ПЛАТНОМ вызове после того, как деньги строки объяснены. Цена решения названа в коде вслух: бесплатный вызов на хвосте СТАРОГО поколения тоже будет взят, то есть оценка завышается — ратифицированное направление. Посадка FC8-free-call-dropped-from-a-paid-generation.
  • [LOW→взято] $0-строка, чей новейший вызов чужой, котировалась $0 без оговорки: переполнения на нуле не бывает, поэтому детектор отката её не видел. Теперь такая строка помечается «не удалось пере-оценить»; skipped-строка остаётся честно бесплатной. Посадка FC8-unestablished-zero-row-published-as-free. ⚠ Существующий случай таблицы, чей комментарий говорил «skipped-строка», диспозицию не ставил — привёл тест к его собственному замыслу и добавил случай без скипа (объявляю по D39.183: поведение сменилось по находке, тест стал строже).
  • [LOW→взято] развилка ЛОГА из Б1 не была прибита — мутация «удалить ветку конца книги» переживала весь пакет. Новый TestTheRunLogSaysWhichKindOfVolumeStopItWas (обе ветки, живым прогоном), посадка FC8-log-fork-at-the-end-of-the-book.
  • [MED→исправлено] отчёт пака называл пять посадок разведочными именами (Y2…, Y3, Z2, X29, Y4), которых в каталоге нет: Б7 завёл их под именами FC7-*, но ссылки остались старыми. Переименованы; grep по каталогу на старые имена → 0, ни одно из них больше не стоит в отчёте как имя гейта.

Второй проход того же проверяющего — по трём осям, вердикт его словами. Дерево ему было пере-сдано после правок; он адресно пере-атаковал свои находки 1, 3 и 6 (все три ДЕРЖАТ, каталожные посадки красные), отдельно проверил новое правило обхода usd() таблицей краевых форм (откат, остаток, эскалационный хоп, skipped, нулевая стоимость) и занижений не нашёл. A — исходный промт: исполнено с остатком (остатки — два схемных остатка строки 232 и отложенный вопрос владельца, все названы и заказаны такими). B — наряд Б1Б9: все девять закрыты (Б8 был закрыт с остатком, см. N1 ниже — закрыт). C — код и отчёты: ГОДНО К ПРИЁМКЕ, блокеров нет. Три его новые находки, все LOW, закрыты здесь же:

  • N1 — строка отчёта говорила «18 заведено дофиксом и проверкой», а раскладка в скобке давала 14 и не называла FC1. Правда: прирост 18 = паком 6 (FC1×4, FC5×2) + дофиксом и разбором проверки 12 (FC6×4, FC7×5, FC8×3). Тот же класс, что чинит Б8, — число одной величины под именем другой; пере-считано командой, она стоит рядом.
  • N2 — условие len(calls) > 0 в метке «поколение не установлено» не было прибито: мутация переживала пакет. Добавлен случай «$0-строка без единого вызова на файле свободна, а не нераскрыта» + запись FC8-empty-cell-disclosed-as-unestablished (красная).
  • N3 — комментарий у той же ветки описывал skipped-строку так, будто guard несущий, тогда как продовые вызывающие skipped-строки сюда не доводят (projectRebill их отфильтровывает, projectBookUSD роняет флаг). Комментарий говорит теперь ровно это: guard защитный, а не несущий, и почему он остаётся. Его диспозицию по находкам 4 и 5 («согласен, входы в отложенный вопрос владельца») принимаю; он же заметил, что находку 4 можно закрыть и без смены семантики — снимком plan-time Carried. Это ВЫБОР, не необходимость, и он входит в тот же вопрос владельца.

Что НЕ удалось и что НЕ проверено (дофикс).

  • Цикл из трёх покупок на флагнутом юните не замерен — см. Б10. Знаю, что не проверено; не чинил, потому что наряд прямо запретил трогать семантику переноса.
  • Состояние Delivered == Carried с исходом класса unitFresh (Б3а) ни одной фикстурой не достигается; инвариант утверждён на сконструированном состоянии, и это сказано в самом тесте.
  • Живого прогона с платными вызовами не было ни в паке, ни в дофиксе.
  • Оба остатка строки 232 (первая редакторская стадия; прерванная пере-делка) по-прежнему открыты и требуют схемного носителя.
  • Четыре находки проверяющего названы, но НЕ чинятся — все четыре суть входы в отложенный владельцем вопрос о семантике переноса, и наряд прямо запретил её трогать:
    1. Клауза «finished OUTSIDE this grant» ключуется на Carried ПОСЛЕ reconcile, поэтому исчезает, когда все перенесённые юниты флагнулись: оператор видит «2 PAID FOR BUT FLAGGED», но не то, что обе оплаты шли вне гранта. Воспроизведено: VolumeStop{MaxUnits:2, Delivered:2, Carried:2} + два флага класса unitCarried.
    2. Перенесённый юнит с ПРОТУХШИМИ черновыми строками пере-покупает всю цепочку вне гранта, тогда как хелп флага обещает «дописать недостающее». Воспроизведено проверяющим: granted()=0, два вызова провайдера на один юнит.
    3. Подсказка в докстринге Delivered ключуется на delivered > max_units и молчит в форме «весь остаток перенесён», где delivered == max_units (это же Б10 наряда).
    4. Цикл из ТРЁХ последовательных покупок на флагнутом юните не гонял никто — ни приёмка, ни проверяющий, ни я.
  • Выживание трёх гарантий ФЧ-1 на дереве ДО пака проверяющий сам не воспроизводил (принял по моим красным посадкам); я это делал в паке отдельно, лог в scratch-каталоге сессии.

05.09 — ОТЧЁТ пака «денежный стоп перестаёт быть аварией» (сессия textmachine-main-be, промт BACKEND_MONEYSTOP_SESSION_PROMPT.md)

ПОЛНЫЙ ОТЧЁТ — backend/docs/MONEYSTOP_REPORT.md (происхождение решений, пять рисков зоны по одному, самопроверка, объявления по D39.183, obstacle reporting). Здесь — итог и то, что нужно оркестратору для лендинга. Дерево НЕ закоммичено.

В дереве лежат ЧУЖИЕ правки — вся platform/ (параллельный пак textmachine-main-63). Не тронуты ни байтом. Платного прогона НЕТ: все три оси предъявлены за $0.

Четыре пункта закрыты. (1) строка 271 — правки банка больше не могут писать свои строки внутрь system-сообщения платного вызова: одна граница (internal/membank/wirefence.go), три точки исполнения — дверь отказывает, загрузчик сида отказывает, рендереры пропускают; предел 200 рун, запрет Cc + U+2028/9 + bidi-переопределений (Trojan Source), при этом ZWJ/ZWNJ/LRM/RLM РАЗРЕШЕНЫ (общность §0.1); фолд версии СКОУПНЫЙ, чистая книга хеширует байт-в-байт как до фикса — запинено значением, снятым сборкой 32be78a. (2) строка 277 — отказ резерва защёлкивает волну и не отменяет допущенное; отказ не окончателен при непустом полёте (ждём settle, повторяем тот же резерв); только ОБЯЗАТЕЛЬНЫЕ вызовы ждут. (3) строка 278 (событие) — недостача едет в ceiling, StreamVersion 1.2 → 1.3, денежный леджер в finished. (4) строка 278 (проекция) — цена книги ДО покупки в manifest --json и status --json.

Числа, каждое получено командой (полный список — §6.7 отчёта). ⚠⚠ ТРИ ИЗ НИХ ПРОТУХЛИ ЧЕРЕЗ ТРИ ЧАСА, И ОДНО ПЕРЕВЁРНУТО — поправка в конце абзаца; она найдена ВЕРИФИКАТОРОМ 05.09, не зоной и не мной: тестовых функций 1172 → 1208 (+36), все тридцать шесть в трёх новых файлах; git diff -U0 -- backend | grep -E '^[+-]func Test' ПУСТ — ни одна существующая не удалена и не переименована, два протухших починены внутри тела. Каталог мутаций 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 неожиданных исходов. **⚠ Испр. 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 и следующей фразой запретил его класс («цены вызовов не выходят»). Едет недостача committed+reserved+estimateceiling, поле shortfall_micro_usd (строка 278 называла next_step_micro_usd). Две оговорки в доке поля: при непустом полёте это ВЕРХНЯЯ граница; для day-скоупа поле ОПУЩЕНО (дневной потолок суммирует все книги стора, движковые цифры — одной).
  2. Третье лечение пункта 1 («обрамление как ДАННЫХ») в ТЕКСТОВОЙ форме невыполнимо. lang/data/injection.txt побайтно входит в EmbeddedVersion()cutTagвнутрь каждого unit.id: добавление одной строки пере-чеканило бы id всех книг. Сделано структурно.
  3. res.Volume при денежном стопе НЕ прикладывается. Семь счётчиков VolumeStop — план; денежный стоп оставляет допущенные-и-не-доделанные юниты посчитанными как Delivered, а LeftFresh заниженным на них, и при Left()==0 прогон, вставший посреди книги, объявил бы «дошёл до конца». Восьмого бакета нет ⇒ у денежного стопа СВОЙ леджер Finished.Money{units_resolved, units_deferred} из тех же счётчиков, что и progress.

ЧЕТВЁРТОЕ ДЛЯ ЛЕНДИНГА, и это вход в СТРОКУ 283, а не мой дефект: structure: detected сегодня CJK-ONLY. Сопоставление заголовков в интейке идёт по lang.DefaultCJKSection()КОНСТАНТА (章节節回 + класс CJK-числительных), не данные пары. ⇒ книга в любой другой письменности возвращает none, как бы явно её главы ни были размечены. Асимметрию пак НЕ вносит — движок уже читает данные пары для РЕНДЕРА заголовка (configs/langpacks/*/heading.txt), а РАЗРЕЗ остаётся захардкоженным, и строка 283 называет именно этот раскол работой. Что поле ДОБАВЛЯЕТ: у асимметрии появляется имя на проводе вместо того, чтобы прятаться в числе глав — не-CJK книга честно говорит none, и форма заказа (D39.196) не предложит ползунок в ГЛАВАХ против разреза, которого никто не делал. Классификация сама пар-агностична (спрашивает, какой ПУТЬ провёл границы) и скажет detected без правки Go в день, когда разрез научится читать пару. ⚠ Первую редакцию комментария и отчёта я написала как «пар-агностично по построению» — это было пере-утверждение, поймано собственным проходом и исправлено в обоих местах.

ПРАВКИ ЧУЖИХ ТЕСТОВ — объявление по D39.183 (все три вызваны сменой поведения, заказанной паком): · runevents_test.go — пин «the ceiling event must carry the fact and no figures» СУЖЕН, не снят: белый список ключей (halted|scope|shortfall_micro_usd), запрет любого $, ПЛЮС новое утверждение — book-стоп обязан назвать недостачу, day-стоп обязан её не называть. ⚠ Фраза ратифицирована (D39.106 §2/ПТ-33) — ноту о сужении берёт на себя оркестратор. · wavepanic_test.go, volumepanic_test.goоба ВИСЛИ (panic: test timed out after 1m30s): парковали падающий воркер на <-ctx.Done(), которую вызывал ПОТОЛОК. Потолок больше не отменяет — это заказ пака. Триггер заменён, утверждения не ослаблены.

ПРАВКА ВНЕ ЗАКАЗА, взятая по своему усмотрению: течь резервации на ветке json.Marshal(resp.Usage) (stagerun.go) — возврат без release и без settle. Довод: денежный путь, и у него появился второй читатель — утёкшая резервация ЗАВЫШАЕТ публикуемую недостачу. Ветка практически недостижима, поэтому её посадка занесена аргументированным выжившим, а не находкой.

ЧЕТВЁРТЫЙ КЛАСС ЛОЖНОЙ ЗЕЛЕНИ, найденный в этой смене (общий, не про мой пак): t.Fatalf из ПОРОЖДЁННОЙ горутины — runtime.Goexit не на той горутине: утверждение теряется, прогон висит до таймаута ПАКЕТА. Посадка, чей отказ выглядит как таймаут, неотличима от нагрузки и потому не является посадкойа Makefile зоны сам документирует разброс internal/pipeline 95 → 560 с под параллельными сессиями. Рядом с тремя известными: упавшая сборка, вырожденное утверждение, эквивалентная посадка.

ГОТОВЫЙ ТЕКСТ СТРОКИ БЭКЛОГА (таблица — зона оркестратора, поэтому текст лежит здесь, а заводит его он; уже принят и заведён как строка 291):

Отказ РЕЗЕРВАЦИИ на ретрае не деградирует и не оставляет следа — юнит может заклинить навсегда, а волна не может продолжиться без дыры. maxTokensForAttempt удваивает бюджет на каждой регенерации (disposition.go:398) ⇒ attempt 1 резервирует вдвое больше attempt 0. Отказ ретрая уходит наверх из цикла попыток (stagerun.go:164-167) РАНЬШЕ UpsertChunkStatus (stagerun.go:285) ⇒ чекпойнт attempt 0 есть (реплей за $0), строки chunk_status нет, читающие модели видят pending. Следствия два: (1) если потолок покупки не вмещает attempt 1 — юнит не доделается НИКОГДА, каждый резюм реплеит attempt 0 за $0 и умирает на attempt 1, прогон уходит exit 4 при полностью доставленных купленных юнитах; (2) продолжить волну после отказа ретрая нельзя без дыры в непрерывном префиксе — то есть цена глобальной защёлки (недодача юнитов, которые ВЛЕЗАЛИ; разброс резервов внутри волны замерен 2.976×, разбор 04.09) не снимается различителем «свежий/ретрай». Два пути, ВЫБОР НЕ СДЕЛАН: (а) отказ ретрая деградирует во флаг attempt 0 — смена D2.3, закрывает оба следствия; (б) минимальная покупка платформы ≥ step_max_usd движка — закрывает только (1) и стоит продукту минимальной покупки ~5 глав | бэкенд+платформа | скоро | выбор владельца между (а) и (б) + пин | бэкенд-сессия денежного стопа 05.09

ГДЕ ПРОМТ НАПИСАН НЕ ТАК (требование §5-тер(а), полный список — §5 отчёта): §4(3) внутренне противоречив (см. выше) · §4(1) заказывает лечение, невыполнимое без нарушения §4(6) · §3 п.1 называет секцию 15-money-path.md, переименованную 05.09 · §4(2) обосновывает защёлку доводом, который снят самой конструкцией (haltErr — отдельный слот, путь ошибки один при любом W); защёлка оставлена по ДРУГОМУ доводу — продуктовому · §4-тер риск (б) назван мягче, чем он есть: счётчики не «получают новую форму», а врут по шести полям из семи.

Полигон

📌 02.09 · ПИНГ ОРКЕСТРАТОРУ (два входа в бэкенд) + ИТОГ СЛЕПОГО ЧТЕНИЯ. Решения владельца от 02.09 внутри. Носители: пре-реги и результаты — eval/dovodka/blind-read/ (PREREG-BLIND-READ.md + RESULT-BLIND-READ.md с семью эрратами, PREREG-2-BLIND-READ.md + RESULT-2-BLIND-READ.md), прибор дрейфа — eval/dovodka/dreif.py.

  • РЕШЕНИЯ ВЛАДЕЛЬЦА 02.09 (ратификация за оркестратором). (1) Дефолт редактора — low, бремя доказательства на том, кто включает дорогой режим. (2) Вопрос «off против low по качеству» закрыт как неизмеримый этим прибором — судейских реплик не покупать. (3) Питон-прибор дрейфа пишет полигон (сделано), настоящий прибор — в движок, это пинг ниже. (4) Покупка 50 глав на длину отложена до прогона в бэкенде (слово владельца).

  • ⚠ ВХОД 1 — офлайн-пересчёт по уже оплаченному тексту (tmctl recheck или равное). Проверки движка исполняются ТОЛЬКО в момент генерации; готовый текст в базе перепроверить нечем, и потому частота ложных тревог пост-чека не измерима без покупки. Полигон закрыл дыру питон-двойником (dreif.py), но это не тот же прибор: у движка стеммер целевого языка и сохранённые формы, у двойника — сопоставление по началу слова. Два «детерминированных» прибора с разными ответами — тихий дрейф нормы; строку в бэклог просит полигон, решение за оркестратором.

  • ⚠ ПОПРАВКА К ЭТОМУ ПИНГУ (02.09, позже в тот же день): входов НЕ ДВА, А ЧЕТЫРЕ, и «включить гейт» из них самый мелкий. Разбор начат вопросом владельца («в бэкенде нет майнинга term — „мастер гу“ не замайнится»). Проверено исполнением: майнинг term РАБОТАЕТ (68 записей класса term, 蛊师 → гу-мастер в банке есть), но владелец прав по сути — цепочка «намайнил → классифицировал → подписал → инжектнул как закон → проверил» рвётся в ЧЕТЫРЁХ местах, и замеренный дрейф (30 ключей из 102 несут >1 передачу, максимум 7 форм) — их следствие.

    • (1) term — класс-умолчание, а не решение. backend/internal/pipeline/banknote.go:79 дословно: «bankTypeOK is the accepted type set; anything else falls back to "term" (a benign default)». Две трети банка пробы (68 из 102) сидят в этом умолчании.
    • (2) Классификатор умеет различать term, но в пробе НЕ ДОБЕЖАЛ. Определение в backend/prompts/zh-ru/classifier.md:20-23 точное («реалия, понятие, предмет, материал, вещество, класс существ — всё, что переводится ПО СМЫСЛУ», пример 元石 term). Однако лог пробы: batches_planned=8 · batches_running=6 · classify_batches_dropped=4 при budget_usd=0.05 против estimate_usd=0.0978; итог unanswered=7, reclassified=5. Движок сам предупредил: «this bank is PARTIALLY consolidated — a budget cut a pass, so some terms were never offered to the role at all». ⇒ типы выставила банкнота или умолчание кода, а не тот механизм, который умеет.
    • (3) Промпт банкноты недоспецифицирует класс term. backend/prompts/zh-ru/translator-banknote.md: просит «новых имён собственных и терминов», список типов даёт, но определения term нет, а единственный пример — 师父 наставник title, то есть образец уводит в титулы; лимит «не более 20 строк» на фрагмент вытесняет понятия в пользу имён (имена заметнее). Правка промта — не Go и пары не касается.
    • (4) Инжект фильтрует по ПОДПИСИ, а не по классу. backend/internal/membank/memory.go:663: status == "approved"Confirmed, иначе Ambiguous; priorityRank (там же, ниже) вытесняет неподписанное первым при token-бюджете (glossary_token_budget: 800 на 102 записи). При approved=0 весь банк едет «неуверенным кандидатом» — форма не объявлена законом, и удерживать её нечему. Это и есть механизм дрейфа 蛊师 («гу-мастер» / «мастер гу») и 元石 (семь форм).
    • ⚠ (5) НАБЛЮДАЕМОСТИ НЕТ на редакторской стадии. retrieval_state в базах пробы держит 35 строк, все под DRAFT-снапшотом (8d5721f65596), под edit-снапшотом (b76ab168d95b) — НОЛЬ строк. Доехал ли банк до редактора и сколько записей вытеснено бюджетом, из артефактов узнать НЕЧЕМ. Все счётчики на черновой стадии нулевые закономерно: банк рождается ИЗ черновика, на нём его ещё нет.
    • Порядок, который из этого следует (предлагается, решение за оркестратором): наблюдаемость инжекта на edit-стадии → бюджет классификатора (пять центов режут половину работы) → определение и пример term в промте банкноты → подпись банка и заполнение форм → и только потом жёсткий режим гейтов.
    • ⚠ ТРИ ПОПРАВКИ К МОИМ ЖЕ УТВЕРЖДЕНИЯМ ВЫШЕ, найдены консилиумом 02.09 и пере-проверены мной исполнением. · (5) сформулирован неверно в ПРИЧИНЕ. «Ноль строк под edit-снапшотом» — не разрыв, а схема: PRIMARY KEY (book_id, chapter, chunk_idx) без snapshot_id (store/migrate.go), редактор мержит в ту же строку, и snapshot_id в ней — просто последнее записанное. Вывод «наблюдаемости нет» ОСТАЁТСЯ верным, но дыра в другом: счётчики инжекта редакторской волны не пишутся никуда (pipeline/chunkrun.go:202). · «ни один $0-гейт не поймал латиницу» — неточно. Детектор латиницы ЕСТЬ и вызывается всегда (checks/cheapgates.go:192, lintLatinResidue), но по построению он наблюдатель, а не вердикт: дословно cheapgates.go:22-27 — «They are OBSERVABILITY, never hard gates… never changes a chunk disposition». Гейт видел и молчал, потому что так устроен. · Источник «cultivation» — НЕ glm-5. Пере-проверено по стадиям: слово рождается в ЧЕРНОВИКЕ (deepseek-v4-flash, 7 клеток) во ВСЕХ руках, потому что черновик общий; редакторы DeepSeek его вычищают (0 в финальных текстах p9-low/p7-off), а glm-5 — нет (3 клетки на edit, 2 доживают до финала). Значит это дефект не породителя, а фильтра, и прежняя формулировка «glm-5 опознаётся по латинице» верна по факту, но неверна по причине.
    • Улика к строке 46, а НЕ находка: полный провал языка цели. books/dovodka/dv-i-z8-fb9ed5709e.json — глава пары zh→ru переведена целиком на английский: пере-считано мной, 7104 латинских знака, 0 кириллицы, finish=stop. ⚠ Прежняя формулировка «главного, чего в пинге не было» СНЯТА 03.09: это уже заказанная работа. Строка бэклога 46 называет ровно этот случай дословно — «Экран целевого языка: „полный связный перевод на английский" проходит»; дизайн пака заморожен владельцем (D39.92 п.1 closed-set + D39.93 изолированный модуль), предгейт — строка 113 (фикстура ~20 off-target). ⇒ ценность вычитки здесь — не гейт придумать, а дать строке 46 живую улику с боевого прогона.
  • 📌 03.09 · ВЫЧИТКА 17 ГЛАВ БОЕВОГО ПЕРЕВОДА ($0, 17 агентов Opus, по агенту на главу с исходником). Материал — p9-low (дефолт редактора по решению владельца 02.09), экспорт tmctl export --pairs. Инструкция вычитчику разделяла ДВА уровня: «читатель споткнётся» (против них меряется планка владельца ≤2 на главу, D39.20) и «мелочь корректора».

    • Планка НЕ взята: 59 блокирующих претензий на 17 глав = 3.5 на главу. В планку уложилась 1 глава из 17. При этом все 17 вычитчиков независимо ответили «читается как книга» = ДА.
    • Классы (всего / из них ловится детерминированно): смысл-искажён 12/0 · имя-термин-непоследователен 10/10 · translationese-грубый 9/2 · род-гу 7/6 · логика-действия 6/1 · иное 5/3 · язык-не-тот 4/4 · пропуск 3/3 · меры 3/3. ⇒ механизируемо 32 из 59 (54%) ПО ОЦЕНКЕ ВЫЧИТЧИКОВ; ⚠ оценка завышена: прогон существующих RunCheapGates по 11 цитатам дал 1 срабатывание из 11 (сегодняшний код берёт заметно меньше).
    • Остаток, который не берёт ни один детерминизм: 12 искажений смысла + 6 сломанных мизансцен = 1.1 на главу — то есть НИЖЕ планки владельца. Образец (гл.1): «перекрыл им путь, сделав шаг в сторону» — по-русски «посторонился», фраза противоречит себе; в оригинале 横跨一步 = шагнул НАПЕРЕРЕЗ.
    • Найдено проверкой самих вычитчиков (системнее, чем они доложили): заголовки глав теряются. Исходник даёт 第二十六节:一切组织的本质 — номер И название; движок кладёт в заголовок только номер (chunk/chunker.go stripHeading/ApplyHeading), название сваливается в тело как обычная строка. Дальше как повезёт: название уцелело у 11 глав из 17, потеряно у 6 ⇒ на 2283 главах это ~800 глав без названия вперемешку с озаглавленными. Ловится тривиально: заголовок состоит только из номера. Улика к строкам бэклога 160/161/162 и 201.
    • Сырьё вычитки: /tmp-экспорт не сохранён (волатилен), воспроизводится командой tmctl export --config arms/p9-low.book.yaml --pairs; вердикты 17 агентов — в задаче воркфлоу wfofkln2i.
  • 📌 03.09 · КАНОН СУЩЕСТВУЕТ, ПОДПИСАН И НЕ ПОДАН В СТЕНД (проверено исполнением). ~/books/gu-zhenren/guzhenren-seed-v2.yaml58 записей, из них 53 status: approved, 16 с полем gender. В нём ровно те термины, на которых спотыкались вычитчики: 资质 → талант (канон владельца D39.21), 元石 → первобытный камень (а в пробе намайнилось 7 форм), 甲等/乙等/丙等 → класс А/Б/В (а в переводе «категория C» ЛАТИНИЦЕЙ), 蛊师 → гу-мастер. В ~/books/gu-zhenren/probe-4axes/book.yaml ключа glossary_seed НЕТ — 0 вхождений, и шапка стенда объявляет это сознательно: «Сид НЕ подключается — банк рождается майнером + банкнотой, как в холодном прогоне». ⇒ Прежняя формулировка «банк не подписан» (запись 02.09) НЕТОЧНА и настоящим уточняется: не подписан МАЙНЕНЫЙ банк, а подписанный канон просто НЕ ПОДКЛЮЧЁН. Весь измеренный дрейф (30 ключей из 102 с >1 передачей) — дрейф конвейера с отключённым каноном. Контр-факт на той же книге: с подписанным банком эффективная консистентность 99.3100% (Д50.2, 375548 пар). ⚠ Записи в сиде НЕ ХВАТАЕТ поля gender (средний род прописан прозой в note) и стоит allow_short: false при minKeyLenHan=2 ⇒ односимвольный ключ структурно вне автомата. Это две строки ДАННЫХ, не код.

  • 📌 03.09 · СВЕРКА С ПЛАНОМ ПОСЛЕ ЗАМЕЧАНИЯ ВЛАДЕЛЬЦА — 10 «предложений» из 11 оказались уже заказанной работой. Владелец: «вы рассуждаете без оглядки на ту архитектуру и код, что уже построена или ЗАПЛАНИРОВАНА». Замечание верное: консилиуму давали код и данные вычитки, но НЕ давали целевую архитектуру, ЕДИНЫЙ БЭКЛОГ и журнал решений. Тот же консилиум, подняв прежний контекст, прочитал план и снял свои же предложения. Сверено мной по носителям.

    • Уже в плане: вынести вердикт-поля из хеша = строка 49 (спека backend/docs/D15.2-content-addressed-resume-spec.md) · экран языка цели = строка 46 · заголовки глав = строки 160/161/162 и 201 (гейт пал словом владельца 15.08, D39.136 п.3) · петля ремонта = построена за enabled:false, включение — строка 13 (владелец) · морфо-гейт рода = строка 82 · числа и меры = строка 12 через триггер D39.79 п.4 · критик = строка 2 (владелец).
    • Уже ПОСТРОЕНО: род neuter end-to-end — D39.69 §3 (13-tech-debt-anchors.md: «носитель ПОСТРОЕН»). Остаток по роду «гу» — две строки ДАННЫХ в сиде стенда (guzhenren-seed-v2.yaml:291-300: allow_short: false, поля gender нет) плюс ключ glossary_seed.
    • Противоречит ратифицированному: патч-протокол редактора ↔ D39.108 п.1 «диффы откладываются» · критик как стадия движка ↔ D38.4 п.2 «семантический span-судья — ОТКАЗ» · подпись ~30 ключей поимённо ↔ D39.144 «подписывается ВЕСЬ банк ОДНИМ ОК; пер-термная масс-подпись = инерция» · канал идиом врезкой dst ↔ D38.4 п.1 «глоссарий-сидинг чэнъюй НЕ делаем» · таблица мер ↔ D39.79 п.4 «HARD-value-детектор НЕ строить».
    • Что вычитка дала по-настоящему: улики к уже открытым строкам — 46 (глава на английском), 82 (7 дефектов рода), 142/13 (классы для точечной починки), 160 (6 глав из 17 без названия ⇒ ~800 на книгу), 12 (триггер реопена по числам НАЖАТ: #46/#13/#11). Это подтверждение заказанного, а не новый список.
    • Метод-урок, дороже находок: сутки ушли на переоткрытие бэклога, потому что план не был подан консилиуму. Любой панели, обсуждающей ЧТО СТРОИТЬ, план подаётся вместе с кодом — иначе она уверенно переизобретает заказанное. ⚠ Для полигона отсюда следует и граница: строки 46/49/82/142/160/12 — зона бэкенда, полигон в них не лезет; его законная часть — улики и замер (см. ниже).
  • ⚠ ВХОД 2 — пост-чек банка не имел ВХОДА, а не только был выключен. В пробе gates.coverage.enabled: false и блока gates.glossary нет — это известно; но сверх того: из 102 записей банка ни одна не доведена до approved, и decl пуст у ВСЕХ. Пост-чек проверяет подписанные термины (membank/mempostcheck.go), значит молчал он по двум причинам сразу. Условие включения жёсткого режима записано в самом коде — «после того, как владелец подтвердит точность», а точность мерить не на чем, пока банк не подписан. Порядок для бэкенда: подписать банк → заполнить формы → замер ложных тревог → решение владельца.

  • ИТОГ СЛЕПОГО ЧТЕНИЯ (две редакции, 219 судей Opus, $0.66 на реплику low₂). Редакция 1 дала 18:6 «дешёвая рука лучше» — вывод СНЯТ: судьям показывали усечённый черновик (стадия edit склеивает несколько draft-чанков; в 10 юнитах из 15 опора покрывала 5579%). Редакция 2 на склеенном по манифесту черновике (покрытие 99100%) плюс активные нули (low₁ против low₂): судьи назвали победителя в 29 голосах из 30 на чистом шуме, перекос на шуме (80%) БОЛЬШЕ боевого (70%). Первичные исходы: точность 12:10:8 (p=0.842), художественность 19:8:3 (p=0.070, Холм 0.141) ⇒ различие НЕ ПРЕДЪЯВЛЕНО. Механика вскрыта: в 73 голосах из 74 побеждал вариант с меньшим числом претензий, а счётчик упирался в потолок в половине голосов. Текстовый шум одной руки (0.799) больше межрежимного (0.820).

  • ПРИБОР ДРЕЙФА, первые числа ($0, на уже купленном). Терминов с более чем одной передачей в тексте — 1316% от измеренных; сменивших форму между главами — 68%. Независимым путём (поле spread, считает сам движок): 30 записей из 102 несут >1 передачу, максимум 7 форм у одного ключа (元石: «юаньши · камень юань · изначальный камень · первородный камень…»). ⚠ Разброс МЕЖДУ режимами (0.31.9%) не превышает шум-пола (2.4%, снят по паре реплик одной руки) ⇒ дрейф на этом отрезке — свойство черновика и банка, не редактора; экономия на редакторе к нему отношения не имеет.

  • ⚠ Мои ошибки этого пака, названные вслух: первая редакция пре-рега имела невалидный первичный тест (ничьи в знаменателе против H₀=50% дают ошибку I рода 17.8%) и правило решения с непокрытым пространством исходов; гейт слепоты искал [A-Za-z]{2,} и пропускал одиночные латинские буквы (2325 на руку, слепота при этом не пробита — асимметрия 8%); первый гейт покрытия мерил долю совпавших слов и срезал 14 юнитов из 15, потому что смешивал «нет опоры» с «сильно правил»; первый парсер банка искал src: вместо формата «ключ⇥передача» и печатал «дрейф 0%» на пустых вариантах — отказ пойман гейтом парсера, который теперь в приборе. Сверка с нормами оркестратора post-hoc: риг нарушил «оба порядка» (обе редакции), «полно-evidence окна» (редакция 1), «шум-полы измерены» (редакция 1), «детерминированный скорер > судьи» и D39.61 «вывод на агрегате до вскрытия единиц».

📌 02.09 · ПРОБА РЕДАКТОРА ПО ЧЕТЫРЁМ ОСЯМ КУПЛЕНА И ЗАКОНЧЕНА. Ответ на вопрос владельца «почему редактор дорог» получен: ОН ДУМАЕТ, А НЕ ПИШЕТ. Отчёт — docs/experiments/23-editor-tier.md Д54. Пре-рег стенда — eval/dovodka/prereg-4axes/PREREG.md (фризы c08b547 и 590256a), журнал исполнения со всеми находками — eval/dovodka/prereg-4axes/ISPOLNENIE.md. Стенд — ~/books/gu-zhenren/probe-4axes/. Израсходовано $5.524817 из санкции $9.50; остаток $3.98 НЕ добирался.

  • E0 — ответ на вопрос. Размышление = 77.9% цены редактора без ручки (p7-off) и 76.6% (p9-off); с low — 45.7% и 46.7%; у glm-5 с выключенным thinking — 0.0%. Ретраи: 39.3% и 26.3% цены руки против 1.8% и 6.0% у low.
  • E1 (главный) — эффект ЕСТЬ. Вилкоксон-Пратт, n=17, p=7.6e-05, Ходжес-Леман ×0.283, ДИ [0.175; 0.431]. 19 пар из 40 цензурированы ⇒ величина — нижняя граница: low режет размышление минимум втрое.
  • E2 — цена доставленного знака падает в 2.5 раза (боевая ×0.407 [0.326; 0.605]). Все ЧЕТЫРЕ заранее объявленных варианта, включая строгое delivered и кэш-независимую цену, согласны по знаку и величине.
  • E3 (ось промпта) — НИЖЕ РАЗРЕШЕНИЯ (p=0.487). E4 (взаимодействие) — ниже разрешения (p=0.854), описательный по построению.
  • E5 — опасение плана ОПРОВЕРГНУТО: low БЕЗОПАСНЕЕ. Эхо-клеток у 2, у low 0; обрывов по длине 10 и 9 против 1 и 1. Критерий риска не предъявлен. ⚠ Эхо считается по СЫРОМУ ответу: санитайзер его вырезает, и по отгружаемому тексту эхо не видно вовсе.
  • ИЗ ЭТОГО НЕ СЛЕДУЕТ РЕКОМЕНДАЦИЯ СТАВИТЬ low В БОЙ. Качество не судилось — прямо вне скоупа. Проба даёт цену рычага и снимает подозрение по эху; следующий шаг — судейство качества low против , и теперь его стоит купить.

ГЛАВНАЯ НАХОДКА О ДВИЖКЕ, КОТОРОЙ ПЛАН НЕ ЗНАЛ: АВТО-БАНК РАСТЁТ МЕЖДУ ПОКУПКАМИ. Терминолог перезапускается в каждой руке и, пока у него есть бюджет, доращивает банк — а банк есть ВХОД РЕДАКТОРА. В базе consolidated=51, в первой же руке 81, memory_version уехал, edit-снапшот сдвинулся, движок потребовал --resnapshot. Без гарда это проявилось бы на втором юните уже с оплаченными клетками, а хуже — банк мог вырасти ПО-РАЗНОМУ в разных руках, дав редактору разный вход при внешне исправном кресте. Лечение: гонять базу конфигом БЕЗ стадии edit до неподвижной точки, где терминальное условие — ноль свежих платных строк И ни одного отказа по деньгам (одного «memory_version не изменился» НЕДОСТАТОЧНО). Стоило $0.0352.

И ещё три находки, полезные любому следующему замеру. (1) Проводная улика СУЩЕСТВУЕТ вопреки §3 плана: LOG_LLM_BODIES=1 + LOG_LEVEL=debug пишет сырое тело запроса (obs/logging.go:72llm/httpllm.go:415), только тела, без URL и заголовков — снято, что у low-рук в теле стоит reasoning_effort:"low", у -рук ключа НЕТ, у glm-5thinking:{type:disabled}. (2) Ось креста можно доказать ЗА $0: потолок «база + малая сумма» отказывает первой edit-резервации, но снапшот и джоб к этому моменту уже вычислены; ⚠ потолок обязан лежать НИЖЕ редакторской резервации, но ВЫШЕ батча терминолога, иначе ложная точка выглядит тишиной. (3) tmctl manifest бесплатен и даёт units_total ДО покупкиn пинится числом, а не «сколько получится» (здесь 17 глав → 20 юнитов, а не ожидавшиеся 24).

Самопроверка исполнением (мандат промта §7): агент-контролёр на fable вёл всю сессию по распоряжению владельца и поймал у меня шесть ошибок, из них четыре — одного класса «показания собственного инструмента приняты за факт о мире»: слепой к эху E5, ковариата по первому чанку вместо суммы (15 юнитов из 20), ложная неподвижная точка банка, дефект регулярки, выданный за находку о проводе. Все пойманы ДО того, как повлияли на результат; реестр с классами — Д54.5. Я, в свою очередь, опровергла исполнением одну его находку и одну свою.

⚠ ЧТО ПРЕДЪЯВЛЕНО, А НЕ СПРЯТАНО: гард «зелень на пустоте» прошёл ВПРИТЫК — у p7-off пустых ровно 4/20 = 20% при правиле «>20% ⇒ отказ», а по строгому определению доставки было бы 25% и прибор отказал бы; четыре оплаченных decode_error в p7-off на $0.689 (34.5% цены руки), все на ретраях после обрыва, при нуле в трёх других руках; три юнита выброшены из E1 по R̂ ≤ 0, и два из них — low-клетки с почти нулевым размышлением, то есть выброс делает вывод КОНСЕРВАТИВНЕЕ. Полный список — Д54.4.

📌 29.08 · ФАЗА Д — НА ОБА ГЛАВНЫХ ВОПРОСА ВЛАДЕЛЬЦА ОТВЕЧЕНО, ВОПРОС 0 ОСТАЁТСЯ ОТКРЫТЫМ. Сессия $0, ни одного платного вызова.«Отвечено», а не «закрыто», и разница существенная: на Вопрос 2 ответ дан в форме СЛАБЕЕ, чем звучит сам вопрос — минимакс не проверен (худший ВОЗМОЖНЫЙ жилец не искался), вендоро-независимость архитектуры НЕ проверена (буфер двухвендорен: черновик делает DeepSeek). Первая редакция этой шапки писала «ЗАКРЫТЫ», хотя буллеты под ней несли оговорки — поправлено адверсариальной приёмкой. Отчёт — docs/experiments/23-editor-tier.md, секции Д35Д38. Агент-сессий 154 → 186 из 200. Деньги не тронуты: резерв пака $1.2634 из $18.30 как был.

  • Шаг 4 плана 22.08 ЗАКРЫТ (Д36) — последнее незакрытое условие §7, которое можно было закрыть бесплатно. Дуэль «ролевой промт против его отсутствия» на 16 уже купленных карантинных клетках, панель из 5 армов с ГРУБЫМ ДЕКОЕМ (ZD), 16 читателей fable-5. Промт различим: +1.50 места при пороге 1.13, знаковый p=0.0213, 13 глав из 16 в одну сторону — ровно порог, объявленный пре-регом ДО чисел. ⇒ у прибора ЕСТЬ разрешение на промт-инженерном материале, и всё, что фаза назвала неразличимым, меньше, чем ВЕСЬ ролевой промт.

  • И промт покупает ПРОЗУ, а не БРАК: детерминированный счётчик дефект-классов разницы между «с промтом» и «без промта» НЕ находит (p=0.6875) при том, что грубый декой на той же панели ловит (p=0.0156). Класс Б: текст без промта читатель называет машинным в 9 главах из 16, с промтом — ни разу (p=0.0039). ⇒ минимакс владельца получает третий член: по браку несут гейты, по прозе — ростер И ПРОМТ, и вес промта того же порядка, что вес целой дорогой стадии.

  • Закрыт долг Д34.5, который фаза назвала сама: третий круг панели-0 тем же fable-5 дал первую в фазе оценку СОБСТВЕННОГО шума прибора. Доля чисто читательского шума в пороге = 0.34; смена семейства стоит столько же (0.320.43) ⇒ подмена судьи по средним оправдана. Но хвост разошёлся и воспроизвёлся: полный переворот порядка не случается внутри семейства ни на одной из 16 глав и случается между семействами на той единственной, где сталкиваются брак и проза — обеими межсемейными парами. Вердикт о буфере при этом устоял ТРЕТИЙ раз (p=0.0042 · 0.0213 · 0.0042).

  • 📌 ПИНГ ОРКЕСТРАТОРУ №19 — твой вопрос по Gemini (D39.164) ЗАКРЫТ, и без новых покупок. Выживает ПОСЛЕДНЕЕ системное сообщение, выбрасывается ПЕРВОЕ: разность RE.prompt_tokens RQ.prompt_tokens = 2436 РОВНО на всех 16 главах, sd=0, а постоянного размера из двух системных только первое. Улика исполняемая — eval/dovodka/sysmsg.py, EXIT=0. Твои три поправки (переоценка «физически не может», повторяемость Content.parts[], форум как не-источник) внесены в 00-provider-quirks.md моей рукой, как ты и просил. И следствие для движка правится в ХУДШУЮ сторону, хотя дефект уже закрыт твоим же лендингом 7d0c6f2: до 28.08 хоп в Gemini терял не глоссарий, а ВЕСЬ ПРОМТ СТАДИИrender.go кладёт промт первым, инъекцию второй. Любой исторический результат на Gemini-хопе до 28.08 читать как «стадия работала без своего промта».

  • СВЕРКА --final СДАНА КРАСНОЙ: ТРИ ПРОВАЛА, И НИ ОДИН НЕ ПРО РАБОТУ (диагноз на каждый — Д39.2; гейты я НЕ чинил под зелень). ⚠ Первая редакция этого пинга называла ДВА и недосчитывала R37 — поймано адверсариальной приёмкой исполнением. (1) Переезд обнулил mtime всего сырья — 335 клеток Ф2 имеют ОДИН mtime, поэтому eval/tenant_panel/verify22.py считает границу двойной оплаты как $0.000000 и роняет R71. Клетки времени покупки в себе не хранят ⇒ улика утрачена безвозвратно, результат — нет. (2) Улика R77 («пинг в PROGRESS») ищет заголовок хроники за 15 августа со словами «ФАЗА Д», который вынесение хроники увезло в docs/archive/PROGRESS-2026-08-10-15.md:73=сырьё снято, выводы ПОНИЖЕНЫ. ⚠ Точную строку здесь НЕ цитирую намеренно: первая редакция этого пинга процитировала её — и гейт позеленел от того, что я НАПИСАЛ ПРО ГЕЙТ, а не от того, что исполнил обязательство. Это ровно та подмена, против которой реестр и заведён; поймано собственной сверкой --final ⇒ протух ГЕЙТ, а не обязательство. Норма впредь: время покупки и время ответа писать ПОЛЕМ В АРТЕФАКТ, а не полагаться на файловую систему. (3) R37 — ложный КРАСНЫЙ от нотации, а не от переезда: улика записана как material_ja.py \| grep -q "СТОП\|OK ", разборщик реестра восстанавливает \| в | ОБЕИМ чертам — и трубе оболочки, и альтернации внутри grep, — а без -E черта в grep литеральна. Сам замер зелёный: [OK ] срабатываний нет: 0 из 48 чанков, EXIT=0. ⚠ У этой же строки в прошлом был ложный ЗЕЛЁНЫЙ по той же причине — нотация ломает улику в обе стороны. Реестр я не правил: чинить улики в момент сдачи — это и есть «дописать таблицу под результат».И отдельная находка приёмки, НЕ моя: в журнале агент-сессий есть доисторические дубли токенов внутри прогона d4 (15 токенов заявлены дважды) — они стояли в HEAD до этой сессии, а runs.py --selftest такой класс не ловит.

  • Зона не запускалась на этой машине вовсе: книги переехали в <репозиторий>/books, а риги ходят по Path.home()/"books"65 вхождений в 31 файле (бэклог, строка 217). Поднято симлинком + пере-собран eval/.venv (CPython 3.14.7 против пина 3.14.4 — расхождение названо, риги dovodka/ чистый stdlib). Оба шага записаны в eval/README.md; там же теперь карта зоны dovodka/ — она описывалась ОДНИМ файлом при сорока скриптах.

  • ДЕНЬГИ — свод на ОДНОМ прайсе и в главах Гу, которого у фазы не было (Д41). Боевая связка «черновик flash → редактор pro» = $127 за книгу в 1500 глав Гу, и 90% этих денег — РЕДАКТОР ($114 из $127). Редактор заменяем: тот же черновик с редактором glm-5 = $20, в 6.3 раза дешевле, качество НЕРАЗЛИЧИМО (3 круга чтения, 2 семейства, второй прибор). Однопроходка на той же дорогой модели — $62 (вдвое дешевле связки), на gpt-5.6-luna$7.6, но в прод не идёт: цензур-ось не мерена, китайских клеток нет. ⚠ Сведено расхождение, лежавшее не разобранным: research/04 давал книгу за $715, фаза — за $4168. Оба верны — (а) «книга 1500 глав» в Д29.1 это 1500 НАШИХ единиц ≈ 735 глав Гу, (б) ресёрч считал ВИДИМЫЙ вывод, а у deepseek-v4-pro 46% токенов — размышление, и это ЧЕРНОВИК, а не проверка (96% предложений финала дословно есть в трейсе): модель пишет перевод дважды и обе копии тарифицируются по выходу. Правило для сметы: цену роли считать по total_tokens, а не по длине перевода.

  • ЧТО ОСТАЛОСЬ И СКОЛЬКО СТОИТ (Д38.6, ранжировано): Шаг 7 — 15 глав Гу ПОДРЯД боевым профилем с ЗАСЕЯННЫМИ характер-листами, ~$2 + движковый прогон. Это единственный замер, дающий прибор под Вопрос 0 («консистентность на всю книгу»), и он же готовая in-loop телеметрия прода. Без засева характер-листов результат ложно-отрицателен ПО ПОСТРОЕНИЮ: полей пола в банке нет вовсе, механизма не существовало ни в одном прогоне. Дальше — цензур-ось дешёвой линии $0.20.6 · китайские клетки ~$0.3 · З-2 $0.35 (перед ним $0-долг К-3) · пере-покупка ZP ~$0.4. В резерв $1.26 пункт 1 НЕ влезает — нужна новая фаза и слово владельца ДО начала. Потолки сессией не поднимались.

  • 📌 ОРКЕСТРАТОРУ, мелочь чужой зоны: строка бэклога 217 цитирует якорь eval/conformance.py:48 с ожиданием REPO = Path(...); я добавил в этот файл один импорт, и цель уехала на строку 49. Хук поймал, но правка — в таблице бэклога, то есть в твоей зоне: по правилу самого хука сообщаю, а не чиню. Сама строка 217 в силе и подтверждена этой сессией: 65 вхождений Path.home()/"books" в 31 файле, лечение — одна разрешающая функция корня книг, а не симлинк.

  • 30.08, ПО ЗАМЕЧАНИЮ ВЛАДЕЛЬЦА ПРОЧИТАН ВЕСЬ КОРПУС ФАЗЫ — И ОН ПОПРАВИЛ МОЙ ЖЕ ОТВЕТ В ЧЕТЫРЁХ МЕСТАХ (Д42, Д43). (1) «$11 за книгу» — реальная таблица эксп-22, но по ИЮЛЬСКОМУ прайсу. Пере-счёт тех же клеток по текущему: связка $4043 вместо $1314. (2) Развилка владельца ПОТЕРЯНА всеми планами: PLAN-17-08.md:105-119=РЕШЕНИЕ ВЛАДЕЛЬЦА, КОТОРОЕ ЖДЁТ ЕГО САМОГО — «черновая роль по НАШЕМУ ЖЕ правилу должна уйти с DeepSeek», luna $0.00357 против flash $0.00544. Ни в 21.08, ни в консилиуме, ни в 22.08, ни в моих Д38/Д41 этого пункта нет. ⚠ Приз развилки — 6%, а не разы: редактор съедает 85% связки, и строка плана «$40 против $23» смешивала смену ЧЕРНОВИКА со сменой РЕДАКТОРА. (3) «Однопроходка дешевле связки» снято прибором, который читает ОДНУ главуа по находке владельца (журнал §11) без черновика терминологу не из чего собирать банк, и «на одной главе банк не нужен, на книге в 1500 глав имена разъедутся». Кандидат K7 (однопроходка → майнинг банка из её выхода → фиксер) не мерен ни разу. (4) Конфликт приборов по замене редактора напечатан: Д41 даёт glm-5 неразличимым от dspro по слепому чтению, а счёт ошибок эксп-22 даёт R2 против R0 2.12, Холм 0.0188 — значимо хуже на zh. Кто прав — вопрос приёмке.

  • 30.08, ЖИВАЯ ВАХТА D39.92 ПЕРЕ-СНЯТА — ВЕНДОР-СТРАНИЦА DeepSeek ИЗМЕНИЛАСЬ, И ЭТО БЬЁТ ПО ВСЕЙ АРИФМЕТИКЕ РАЗМЫШЛЕНИЯ (Д44). curl HTTP 200, guides/thinking_mode, 108 336 байт, sha256 f28c4324…. Было (наша запись 10.08): две колонки, у deepseek-v4-pro low маппится в high, «рычаг бюджета размышления существует ТОЛЬКО у flash». Стало дословно: «identical for deepseek-v4-flash and deepseek-v4-pro», таблица одна, low → low; тумблер {"thinking":{"type":"disabled"}} подан как общий. ⇒ у якоря письма ПОЯВИЛСЯ рабочий рычаг размышления, которого не было при всех покупках фазы. ⚠ Это ДОКА, не поведенческая проба — по норме «слаг ≠ модель» перед деньгами нужна живая проба (единицы центов); сессия её НЕ делает без слова владельца. ⚠ Побочно с той же страницы, чего у нас не записано нигде: «Thinking mode does not support the temperature… will have no effect»наш temperature: 0.3 на deepseek-v4-pro молча игнорируется. ⚠ И: effort:"low" у DeepSeek пере-вооружает эхо-мину — рычаг есть, бесплатным не будет.

  • ЧИСЛА ПО ЛУНЕ ПЕРЕ-СНЯТЫ ПОКЛЕТОЧНО ПО ЗАПРОСУ ВЛАДЕЛЬЦА (Д44.6), И ОНИ БОЛЬШЕ, ЧЕМ Я ПЕЧАТАЛ. Однопроходка, те же 16 английских глав, тот же промт, finish=stop 16/16 у обоих: RN (deepseek-v4-pro) медиана $0.02011/клетка, сумма $0.4938 · RL (gpt-5.6-luna) медиана $0.00248, сумма $0.0392 ⇒ 8.1× по медиане, 12.6× по сумме, при качестве, которого прибор не разрешил. Вся разница — размышление: у якоря оно БИМОДАЛЬНО (466 … 19 559 токенов на главу), у луны прибито к ~1 000 явным low. НО ЭТО СРАВНЕНИЕ КОНФИГУРАЦИЙ, А НЕ МОДЕЛЕЙ, и ни одна прежняя строка этого не говорила: якорю ручку не слали вовсе (= high), испытуемому слали low. По собственной норме фазы (Д28) это РАЗНЫЕ армы. ⇒ Замер, который это разводит, стал возможен ровно сегодня (см. пункт выше): те же 16 глав, тот же промт, deepseek-v4-pro с reasoning_effort:"low", смета $0.050.10. Либо снимает с луны восьмикратное преимущество, либо подтверждает его при уравненных ступенях. Самая дешёвая и самая информативная покупка, какую фаза может назвать; ждёт слова владельца.

  • ТРЕТЬЯ ТИХАЯ ПОЛОМКА ОТ ПЕРЕЕЗДА МАШИНЫ, найдена исполнением 30.08: в eval/.env у ВСЕХ СЕМИ ключей пропали подчёркиванияDEEPSEEKAPIKEY вместо DEEPSEEK_API_KEY (и так же GEMINI/OPENAI/XAI/ZAI/KIMI/MISTRAL). Код читает os.environ["DEEPSEEK_API_KEY"] (eval/tenant_panel/roster.py:41=DEEPSEEK_API_KEY), load_dotenv отрабатывает, имени нет ⇒ любая покупка полигона падает KeyError. ⚠ Значения ключей не читались — снят только список ИМЁН и признак непустоты. Файл владельца не тронут, обёртка-переименовалка не написана (это запрещённый молчаливый обход). Чинится одной правкой на стороне владельца. ⇒ Класс назван: переезд ломает окружение МОЛЧА, и каждая поломка вскрывается только исполнением — до этого были пути ~/books (65 вхождений в 31 файле) и обнулённые mtime (Д35.2). Санкционированная владельцем покупка (Д45) стоит готовой и ждёт ровно этого: пре-рег заморожен, арм заведён, провод прочитан, промт сверен побайтно, смета $0.16 при свободных $0.285.

  • РЕЕСТР ПОТЕРЯННОГО (Д43) — прямой ответ на «не хотелось бы расти по энтропии». При каждой смене носителя курса часть намерений не переезжала, и никто этого не печатал. Собрано ~25 позиций: семь развилок на владельце · десять объявленных $0-замеров, которые не сделаны · три долга ЧУЖИМ зонам, где полигон обещал пинг и не пингнул · шесть выпавших из очереди покупок. 📌 Первое, что прошу оркестратора взять: экстрактор epub сносит границы абзацев (HANDOFF-21-08.md:152, консилиум поднял до «починка ДО любого нового en-замера»): пинг обещан 21.08 и так и не сделан, а весь английский материал фазы снят с испорченной подачей. Плюс: английский пар-пакет не заленджен в backend/prompts/. Норма, которую предлагаю завести: новый носитель курса обязан явно перечислить, что из старого НЕ переехало и почему.

  • Незакрываемое панелями, названо прямо: абсолютная база класса Б (Шаг 5.1). Читателя просят назвать худших ВНУТРИ панели — метка сравнительная, норма абсолютная. До отдельной абсолютной рубрики или человека норму «≤1 машинная глава на 25 глав Гу» печатать нельзя.

  • 30.08, ПОСЛЕ КОМПАКТА: КЛЮЧИ ПОЧИНЕНЫ ВЛАДЕЛЬЦЕМ, ПРОБНАЯ КЛЕТКА КУПЛЕНА ($0.038276) — И ГЛАВНОЕ ОНА ОТДАЛА БЕСПЛАТНО (Д45.5, Д46). Несущая улика — не размер размышления, а входные токены: при побайтно одинаковых messages (sha256 сверен исполнением) вызов без параметра дал prompt_tokens 3270, вызов с reasoning_effort:"low"3191, то есть 79. Два контроля детерминизма: замер 05.08 (дефолт и low вернули ОДИНАКОВЫЕ 2124) и пред-полётные пробы самого рига (84 · 84 · 84 · 84 на одном тривиальном запросе, четвёртая куплена 30.08 — то есть дефолтный счёт входа не сдвинулся через смену вендорского сервинга). ⇒ параметр low на deepseek-v4-pro ТЕПЕРЬ ДОХОДИТ ДО МОДЕЛИ, статус квирк-бюллетеня «НЕ УСТАНОВЛЕНО» закрыт в части «доходит ли» (новая запись 3г). ВЕЛИЧИНА среза — НЕТ, и это находка против моего же пре-рега: RN куплен 21.08, RNL — 30.08, а между блоками лежит документированная смена вендорского сервинга (её же зафиксировала вахта Д44) — сравнение приписывает ручке всё, что вендор поменял за девять дней; дрейф из §3б — второй конфаунд и слабее (у него есть знак, и он работает против нуля). Раздел Д45.3 «чего замер не закроет» не назвал НИ ОДНОГО — дефект найден пере-чтением ПОСЛЕ фриза 87dd124, печатаю против себя. ⇒ Лечение одно: оба арма в ОДНОМ блоке вперемежку — и такой замер КУПИТЬ МОЖНО, вчетверо дешевле замороженного: дизайн Д (интерливинг RN2 против RNL на восьми дешёвых главах) стоит $0.0780.133 при свободных $0.2472, n=8 пар, минимальный двусторонний p = 0.0078; гард кассы его пропускает (проверено по коду, гард не тронут). Пре-регистрация — Д47, заморожена коммитом, НЕ КУПЛЕНО: санкция владельца была на ДРУГОЙ дизайн, переносить её я не вправе. Рекомендация: пятнадцать клеток по фризу Д45 (дизайн А) не покупать ни при каком ответе; Д47 — по его слову. ⚠ Первая редакция Д46 утверждала обратное — «ни один неконфаундированный дизайн не влезает» — и это было НЕВЕРНО (пропущена дешёвая восьмёрка, при том что бимодальность нашла та же секция); сломал адверсариальный проход, разбор и цена ошибки — Д46.6, там же единственная находка прохода, которую я ОТКЛОНИЛ (корреляция по порядку вызовов: у всех 16 клеток RN один mtime, порядка не существует). Боевая ступень редактора не тронута (eval/tenant_panel/roster.py — правлен только комментарий, который до сегодня объяснял выбор снятой посылкой; гейт пака пере-снят, расхождение то же единственное mtime-шное).

  • 30.08, Д47 ЗАПУЩЕН ПО САНКЦИИ ВЛАДЕЛЬЦА И ОСТАНОВЛЕН ГАРДОМ ПОСЛЕ ПЕРВОЙ ПАРЫ — А КУПЛЕННОЕ ОКАЗАЛОСЬ ЦЕННЕЕ ЭНДПОЙНТА (Д47.6). Списано $0.134804, ФД-N 3.187585 из 3.30, потолок НЕ поднимался. Побайтно один промт, одна глава b065a92dc0, reasoning_effort не слался НИ РАЗУ: 21.08 модель думала 466 токенов, 30.08 — 17 757. ×38. ⚠⚠ ПОПРАВЛЕНО В ТОТ ЖЕ ДЕНЬ ПО ВОПРОСУ ВЛАДЕЛЬЦА (Д47.7): подавать ×38 как ЗАМЕРЕННЫЙ СДВИГ ВО ВРЕМЕНИ было нельзя — это разность двух ОДИНОЧНЫХ розыгрышей у модели с большим разбросом. По лучшей имеющейся оценке (sd логарифма 0.82 ⇒ одно sd = ×2.3, шесть групп «тот же тег, разные розыгрыши», 18 вызовов, судейская роль) ×38 — это ≈3.1 sd: редко, но возможно ⇒ причина НЕ УСТАНОВЛЕНА, обе гипотезы живы, а чистых повторов одного промта на роли onepass в корпусе НЕТ ни одного. И первый заход к этой оценке был бы десятой ошибкой дня: я сгруппировал вызовы по «модель·глава·роль», получил 100 групп и «разброс ×11» — а группы смешивают армы RN/RC/RB с РАЗНЫМИ промтами (на 27cb3a7e69: 7 061 · 498 · 18 043), то есть мерили разницу инструкций, а не розыгрыша. ⇒ Устояло то, что важнее причины: сравнивать одиночные розыгрыши нельзя ни при какой гипотезе — это осуждает и дизайн А, и МОЙ дизайн Д. Побочно Клейм 1 подтверждён на БОЕВОМ промте: prompt_tokens = 3256 и 21.08, и 30.08 (через девять дней и смену сервинга), а low двигает их ровно на 79; гейт провенанса пройден (Δpt=79, кириллица 1.000, латиница 0). Эндпойнт по правилу: внутри блока ручка дала ×1.40 (меньше ×2.52, полученных через девять дней — конфаунд эффект РАЗДУВАЛ), годных пар 1 из 8, знаковый тест p=1.0 ⇒ «НЕ УСТАНОВЛЕНО», добор глав после чисел запрещён. Носитель — eval/dovodka/stupen.py, написан ДО прихода клеток, селфтест стережёт, что порог достижим только единогласием. Смета ошиблась на порядок, и это моя восьмая ошибка того же класса: $0.0780.133 объявлялись ценой ВОСЬМИ пар, одна пара стоила $0.1348 — я оценил опыт по той самой базе, нестабильность которой опыт и должен был показать. Цена ответов теперь СЧИТАЕТСЯ, а не угадывается (Д47.8): при sd логарифма 0.82 парный дизайн ловит эффект ×2.5 за 13 пар (≈$1.1), ×2.0 за 22 (≈$1.8), ×1.4 за 93 (≈$7.6); отдельный дешёвый вопрос «модель сдвинулась или это кости» — четыре повтора без ручки на той же главе, ≈$0.31. Но приоритет не здесь: ручка даёт ×1.42.5, а рядом стоит рычаг ×711 — смена модели на gpt-5.6-luna (поглавно медиана ×7.1, по сумме ×11.4) — и он упирается НЕ в деньги, а в кап агент-сессий (нужно 16, свободно 14). Тратить доллары на ручку прежде, чем порядковый рычаг прочитан по КАЧЕСТВУ, — плохая экономика. ⚠ Операционное для чужих циклов: отказ гарда возвращает код 1, но в ФОНОВОМ shell set -e цикл не остановил — семь итераций вхолостую, $0.

  • 30.08, ПАНЕЛЬ luna1 ПРОЧИТАНА ВСЛЕПУЮ ПО САНКЦИИ ВЛАДЕЛЬЦА («Да, давай подниму кап»), $0 (Д48). Кап 200 → 215, израсходовано 201. Читались ЧЕТЫРЕ арма на 15 главах (16-я выпала: клетка RN не прошла гейт годности, пропуск напечатан): однопроходка на deepseek-v4-pro · та же однопроходка на gpt-5.6-luna · боевая связка · её вторая генерация как собственный шум прибора. Сначала поправка к моему же предложению: развилка владельца от 17.08 — про ЧЕРНОВУЮ роль, а её приз пере-считан в Д42.1 как 6%, а не разы (редактор съедает 85% связки) ⇒ читать «луну как черновик» значило бы потратить кап на шестипроцентный рычаг; читался порядковый (×711). Результат: средние места Z0 2.33 · ZF 2.33 · RN 2.53 · RL 2.80; близнецы расходятся на +0.00 при пороге 1.06 (прибор без смещения), якорь↔RN +0.20 при пороге 1.30 (p=0.79), якорь↔RL +0.47 при пороге 1.26 (p=0.58), очно RL против Z0 — 6:9. дешёвая луна НЕ ОТЛИЧИМА по качеству ни от дорогого дипсика, ни от связки.Но: разрешение прибора грубое — два прогона ОДНОГО конвейера расходятся на 1.33 места из 4, то есть разрыв луны это треть собственного шума; направление, хоть и незначимое, против луны; панель не трогает банк/консистентность на всю книгу, цензур-ось жанра и перенос на zh. Это ПЕРВЫЙ круг, вердикта ещё нет — правило конъюнкции требует повтора. Дисциплина: ключ закоммичен ДО ответов, обёртка — замороженный 15cfac60, модель читателей сверена ИСПОЛНЕНИЕМ (во всех 15 транскриптах claude-fable-5). Второй круг упирался в ОДНУ сессию — моя арифметическая ошибка при подъёме капа (осталось 14, нужно 15); резать панель до 14 глав решением сессии запрещено. ВТОРОЙ КРУГ ПРОЙДЕН (кап 215 → 220 по слову владельца, Д48.5): вывод ПОВТОРИЛСЯ, конъюнкция закрыта. Средние места круг 1 → круг 2: Z0 2.33 → 2.20 · ZF 2.33 → 2.53 · RN 2.53 → 2.60 · RL 2.80 → 2.67; якорь↔RL +0.47 (порог 1.26, p=0.58) → +0.30 (порог 1.11, p=0.77), то есть отставание луны во втором круге даже СОКРАТИЛОСЬ. Круги разведены по норме рига (ответы первого унесены в krug1/, второй писал по ТЕМ ЖЕ пакетам; свод первого из подкаталога воспроизвёл прежние числа до сотой); модель всех 30 читателей сверена по транскриптам. ⚠ Регистратор отработал как сторож: пере-заявить те же главы отказался, пока сессии первого круга не закрыты (ГОНКА СЕССИЙ). ⇒ однопроходка на gpt-5.6-luna неотличима по качеству от однопроходки на deepseek-v4-pro и от боевой связки на 30 слепых чтениях, при цене ниже — ⚠ но число «7.1× по медиане» я подавал НЕВЕРНО, поправка в Д48.6 по вопросу владельца. (1) В знаменатель попала ПУСТАЯ клетка дипсика (100b088f71, ноль знаков, та самая, что не прошла гейт годности): на 15 годных пар медиана 10.5×, по сумме 12.0×; побочно — непригодную клетку выдал дипсик, 1 из 16, у луны 0 из 16. (2) Тяжелее: медиану тут вообще нельзя приводить — распределение ДВУГОРБОЕ (восемь глав ≈2×, восемь ≈20×, посередине пусто), и она скачет 7.1 → 10.5 от выброса одной клетки. Честно: от 1.3× до 34×, и величина следует за тем, сколько дипсик надумал. (3) Разложение: 87% цены дипсика — размышление (разброс по главам ×42: 46619 559), у луны 49% и ×3 (5111 535); контрфакт «дипсик думает как луна» даёт всего ×2.9 — это чистый прайс и накладные, остальное объём размышления. (4) ⚠ Конфаунд в силе: дипсик ехал без ручки (дефолт high), луна на явном low; ручка стоит ×1.40 (Д47.6) — сузит, но не закроет. (5) ⚠ Воспроизводимость самой луны не мерена ни разу (0 групп повторов на 749 вызовов), а её reasoning_tokens подозрительно кратны 512 — возможен блочный учёт, проверить до смет. Переключение — решение владельца, и перед ним стоит незакрытый гейт, названный им самим 16.08: у однопроходки нет черновика, из которого терминолог добывает свидетельства для банка (Д42.3).

  • 30.08, ЖИВАЯ СВЕРКА ПРАЙСА GEMINI ПО ВОПРОСУ ВЛАДЕЛЬЦА — ОДИН ПИН ВДВОЕ ЗАВЫШЕН (квирк-бюллетень, раздел прайса; источник ai.google.dev/gemini-api/docs/pricing). gemini-3.1-flash-lite — пин верен ($0.25/$0.025/$1.50). gemini-3.6-flash: у нас $1.50/$0.15/$7.50, у вендора дословно «$0.75 through December 31, 2026», то есть выход сегодня $3.75 — наш пин это ПОСЛЕ-промо цена, сметы на этой модели завышены ×2.Пин я НЕ правил сознательно: roster.cost() считает клетки ИЗ ПИНА, и правка переписала бы стоимость 8 уже купленных клеток (Д32.11 — леджер есть оценка) ⇒ решение за владельцем. gemini-3.1-pro-preview верен для ≤200k, но у вендора есть не записанный у нас тир >200k ($4/$0.40/$18). И на странице есть gemini-2.5-flash-lite — $0.10/$0.01/$0.40 выход, втрое дешевле самой дешёвой нашей модели; в смету брать НЕЛЬЗЯ: 2.5-серия имеет shutdown 16.10.2026 и интермиттентный 404 при живом слаге, качество и эхо не мерены. Урок для всех пинов: промо-цена с датой окончания попадает в ростер как постоянная и тихо врёт — у пина обязана быть дата и оговорка о промо.

📌 ПИНГ ПОЛИГОНУ от оркестратора №19 (28.08, D39.164) — вендор-вердикт по Gemini для docs/experiments/00-provider-quirks.md. Материал добыт бэкенд-сессией (curl по вендор-доке, не пересказ), но файл — ВАША зона, вписываете вы. ⚠ Вендор-основание ДОСЛОВНО, со ссылкой и датами снятия, уже лежит в backend/configs/models.yaml у провайдера gemini (греп ВЕНДОР-ОСНОВАНИЕ) — сюда не переписываю. Строка 157 квирков несёт ТРИ утверждения сильнее источника: (1) «слой ФИЗИЧЕСКИ не может пронести больше одного системного» — вендор говорит про НАТИВНЫЙ systemInstruction, а что делает с двумя системными OpenAI-совместимый ШИМ, не документирует нигде; (2) «уход на нативный API проблемы не решает» — верно по сути, не по причине: Content.parts[] ПОВТОРЯЕМОЕ, и нативный API МОЖЕТ нести N системных текстов как N частей ОДНОГО Content; (3) «форум Google» — НЕ вендорский источник: тред discuss.ai.google.dev/t/86097 — два поста, оба от НЕ-сотрудников (staff=false), 30.05.2025, ответа Google нет, а читается наравне с нашим замером. Открыто честно: «выживает ровно одно» против «не выживает ни одного» не разрешено — маркер пробы приписан к msgs[0], и его отсутствие совместимо с обоими чтениями, а зеро-системного контроля в скрипте нет. Твёрдо: НЕ склеиваются (prompt_tokens 2994 → 535) и first-wins ложно. Дешёвое решающее доизмерение: тот же скрипт, маркер на ПОСЛЕДНЕЕ системное плюс user-only базовая клетка. ⚠ Граница: проба гонялась на gemini-3.1-flash-lite, а в цепочке эскалации стоит gemini-3.1-pro-preview — слой тот же, слаг другой. Для движка безразлично: склейка на нашей стороне заленджена (D39.164).

ИТОГ ПОЛИГОН-СЕССИИ 23.08 — ШАГ 1 ПЛАНА 22.08 ЗАКРЫТ (панель-0, $0). Отчёт целиком — секция Д32 docs/experiments/23-editor-tier.md; фризы bedc39a, 9e33a1b; денег не потрачено (панель собрана на уже купленных клетках). Вердикт (интеракция «архитектура × жилец на ИСПЫТАННЫХ жильцах», не минимакс): слабый жилец glm-5 РЕДАКТОРОМ над боевым черновиком неотличим от боевого deepseek-v4-pro в той же роли (разрыв средних мест +0.00, p=0.80), а ОДНОПРОХОДКОЙ различимо хуже (+1.12 места при пороге 0.99, знаковый p=0.0042, +13 фаталов p=0.0312) ⇒ буфер архитектуры существует и замерен — ⚠ на 16 главах. ДЛЯ БЭКЕНДА: в 2 окнах из 8 с первым лицом пол рассказчика по главе НЕ УСТАНАВЛИВАЕТСЯ вовсе (эталон снят вслепую тремя независимыми чтениями на главу), а полей пола в банке НЕТ (~/books/role-topology/bank-en.json, 25 терминов) ⇒ закрыть эти ~25% может ТОЛЬКО книжная память; смыкается со строкой бэклога 210. ⚠ ОТКРЫТО НА ВЛАДЕЛЬЦЕ: сверить $17.04 с реальным счётом DeepSeek может только он. Долг В21 (сверка кассы двумя путями) ИСПОЛНЕН, результат отрицательный: сверка на диске НЕВОЗМОЖНА в принципе — cost_usd вычисляется нашим же roster.cost (buy.py:93-95), а не приходит от вендора; на 213 клетках у четырёх вендоров из шести арифметика сходится до последнего знака, а «офф-пик = ½» в ЗАПИСАННЫХ ценах НЕ наблюдается.

⚠ Пинг оркестратора №18 — 20.08 (протухшие цены в квирках, чинить вашей рукой). docs/experiments/00-provider-quirks.md до сих пор утверждает, что цены после катовера НЕ изменились («flash $0.14/$0.28»). Это опровергнуто пере-пином 1315.08 (D39.137): таблица запинена ПИКОМ — flash 0.44/1.32 при кэш-хите 0.014, pro 1.32/3.96 при кэш-хите 0.044 за 1M (сверено с backend/configs/models.yaml:182,198=cached_per_m и телом D39.137 §2а), и счёт шиппинга = 100% DeepSeek ⇒ ×4.24.4 в пике. Квирки — ваша зона, рукой не трогаю; поправьте при ближайшем касании, потому что по ним считают деньги проб. ⚠ ВТОРОЙ пункт этого пинга СНЯТ 05.09 как ЛОЖНОЕ ОТРИЦАНИЕ оркестратора. Он утверждал, что факт про пиковые окна цен «в квирках ОТСУТСТВУЕТ (греп = 0)». Факт ТАМ ЕСТЬ (docs/experiments/00-provider-quirks.md, греп ПИК DEEPSEEK) — и несёт поправку, которой не было в моей копии: пик только ПО БУДНЯМ, выходные целиком идут по офф-пику. То есть оркестратор, живший по своей копии, отодвигал платное на вдвое дороже по выходным. Копия снята, единственный носитель — квирки. Отрицание было получено грепом, который не мог сработать; урок общий: команда, на которой стоит отрицание, приводится в тексте, чтобы её мог воспроизвести другой. ⚠ Третий пункт того же аудита (eval/README.md держит мёртвый СТОП на платные прогоны) сведён ниже, в пинг №20 — один носитель на факт.

ВТОРОЙ пункт этого пинга ПЕРЕ-СНЯТ 05.09: спора нет и не было. Он утверждал, что квирки и docs/STACK.md говорят «ручки эффорта у deepseek-v4-pro НЕТ» — оба говорят ОБРАТНОЕ (квирки §3г: «параметр low на pro ТЕПЕРЬ ДОХОДИТ ДО МОДЕЛИ», $0.038276, 79 prompt_tokens; STACK.md:11 — то же). ⚠ Это был ЧЕТВЁРТЫЙ носитель фантомного противоречия, снесённого D39.200 п.4(а), и он пережил первую зачистку. Живой остаток один и он не спор: вендор-сверка САМОГО МАППИНГА (low → что именно) и ВЕЛИЧИНА эффекта — замера поведением после 13.08 нет ни у кого. Это боевой РЕДАКТОР и апекс эскалации. Закрывается вендор-сверкой, а не выбором стороны (гардрейл владельца) — и вы это только что делали по Gemini, то есть заход дешёвый. Носитель в трекере — строка 237(б).

ПИНГ ОРКЕСТРАТОРА №20 ЗОНЕ — ТРИ ПРОТУХШИХ МЕСТА, все три ЖИВЫ на 02.09 (правки зонные, рукой не трогаю).

  1. eval/README.md первой врезкой держит СТОП на платные прогоны — «Платные прогоны/докупки СТОП до ре-пробы (бэклог-строка 74)». Строка 74 закрыта (D39.95), ограничение пало лендингом 112 (D39.97), pipeline-c1.yaml несёт reasoning: "low" с объяснением, а зона всё это время платно гоняет фазу Д: врезка объявляет запрещённым то, что делается ежедневно, и этим обесценивает все прочие ⚠ в файле. Живым из неё остаётся только ⚠0731 (смена весов под слагом) и стохастичность эха. ⚠ Пункты 2 и 3 СНЯТЫ 05.09 — зона их закрыла, пинг об этом не знал. (2) eval/README.md:40 уже говорит «не один скрипт, а зона из ~40», а docs/experiments/README.md несёт строки и 22, и 23 (:40, :41). (3) naklon.py в main ВЛИТ: git ls-tree -r HEAD --name-only -- eval/ | grep -c naklon → 1, и в eval/dovodka/ у HEAD 90 отслеженных файлов, а не 42. Живым остаётся только пункт 1.

ФАЗА Д «ДОВОДКА ЭКСП-22/23» — ИДЁТ.Живое состояние фазы живёт В ЗОНЕ, не здесь (eval/dovodka/ — планы, консилиум, ревью; свежий носитель курса зона называет сама), приёмка фазы — у ПАРАЛЛЕЛЬНОГО оркестратора, деньги и цепь потолков — eval/dovodka/money_d.py (PACK_CEILING/CEILINGS), а не литералом здесь: три поколения записей в одном месте и были причиной, по которой состояние фазы стало нечитаемым.

(Хроника фазы Д — записи 10.08 (сессия №1) и 15.08 (сессия №2, сквозной аудит дуги 19→23 и пере-судейство tier) — вынесена в archive/PROGRESS-2026-08-10-15.md с тремя поправками в шапке: потолок, закрытые пункты листа владельца, протухшие «долги». Открытым на владельце из неё остаётся ОДИН пункт — возражение Sol по проходу tier.) Диспозиция оркестратора №17 (15.08), живая до приёмки фазы Д: просьба хендоффа «эррата zh-канона: пере-сборка = правка закрытой оси, ратифицирует оркестратор» (docs/POLYGON_PHASE_D_HANDOFF.md, греп Пере-сборка = правка закрытой оси — файл дирти, номер строки не ставим по норме D39.179 п.4; завышение +0.0039, вердикты не двигает) — к ПАРАЛЛЕЛЬНОМУ оркестратору при приёмке, не к движковому (приёмка фазы Д — его зона, №17 полигон не трогает по слову владельца). Прожитое из записи (вторая передача и мелочи аудита корпуса) — archive/reports/CORPUS_AUDIT_2026-08-15.md; санкции владельца по деньгам фазы и замене ja-книги — D39.136 п.1.

(Память · Голос и состояние · Ридер-IDE — ЗАКРЫТЫЕ секции (D39.125): темы исполнены/переехали в зонные журналы; хроника — в архив-слайсах. Фронт пишет ТОЛЬКО в frontend-PROGRESS.md.)