636 KiB
Журнал прогресса
⟶ ТЕКУЩЕЕ СОСТОЯНИЕ (на 2026-09-07, голова D39.225 — КУРС: движок и платформа до «работает и отдаёт результат», фронт ЗАМОРОЖЕН и 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,epubcheck5.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 находки в собственной работе. Живой остаток зоны — строки 333–339 (шов-близнец и пять описаний, лгущих оператору) и 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. Заведены строки 344–350, дописки в 86/114/119/182/224; «переписать» не получил ни один из одиннадцати долгов. Ратифицированы ПОРЯДОК (шаг 0 параллельно дизайну 161 → шаги 2+3 ОДНИМ окном перенарезки, wire-очередь 182 ложится в него же → шаг 4 аддитивно) и ФОРМА запретов (жёсткие — только под ратифицированной базой, прочее — условия с механизмом, чтобы не спорить с дизайн-паком). Пак шага 0 ✅ ЗАЛЕНДЕН 07.09, актD39.225(две смены поведения названы, вторая денежная: прогон по арму теперь покупает банковый контур). Промт был —docs/BACKEND_GATES_NOT_PROSE_SESSION_PROMPT.md, $0 и снапшот-нейтрально: строки 344 · 345 · 346(а) · 348 · 224, попутно 349/350. Прошёл оба рубежа; вход зоны зелёный (go test ./... -count=1→ 19ok, 0 FAIL, 4 пакета без тестов). ⚠ Единственная заказанная смена поведения — экспорт банка на стопе, и её форма ЗАДАНА аддитивной: перенос засева в ветку стопа запрещён явно (уводит НЕПОДПИСАННЫЕ строки в глоссарий, а те инъектируются законом ⇒ двигаютmemory_version). Снапшот-нейтральность требуется доказать байт-равенством снапшотов. ⛔ ЧТО ЖДЁТ СЛОВА ВЛАДЕЛЬЦА, поимённо: строка 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 показал отмену ДО ухода запроса (латентность 20–31 мс,model_actualпуст, токенов ноль), и вся книга сходится до микро-доллара по трём источникам (request_log0.278319 ·spend.committed_usd0.278318752 · платформенныйcommitted278319 микро). ⛔ ЗАТО HALT НА ПРОГОНЕ, КОТОРЫЙ ПРОДВИНУЛСЯ, ЖЖЁТ — отдельная находка того же прогона и свежая датированная точка строки 78 («леджер = НИЖНЯЯ граница»). Четыре редакторских вызова ушли параллельно; один дошёл ($0.063404) и своим коммитом сорвал потолок, три других отменены в тот же миг, отработав 120756, 156469 и 156470 мс — и легли в леджер нулём. Незаписанное ≈ $0.05–0.19 на ОДИН halt против $0.278 за всю книгу, то есть механизм, защищающий от перерасхода, сам создаёт неучтённый расход. ⚠ Списание провайдером НЕ доказано (биллинга у нас нет) — утверждается ровно наблюдаемое: вызовы шли 2–2.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 настоящего перевода прошёлepubcheck0/0/0/0 и передан владельцу. ⚠ ЭТОТ АБЗАЦ ЗАКРЫТ 04.09 и оставлен как история: дверь выдачи ПОСТРОЕНА и заленджена (adf5e53, D39.194), смонтировано 18 операций из 21 (три адреса двери:createExport/getExport/downloadExport), долгП-17зона пере-сняла. Прежняя проверка «grep -rn 'createExport\|getExport' platform/internal/— пусто» БОЛЬШЕ НЕ ПУСТА и как гейт не работает. Не смонтированы по-прежнемуgetRun,updateBook,deleteBook—updateBookнесёт продуктовое следствие, строка бэклога 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.yaml—0.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 main→ rc 1,git log main..origin/main→afa7700 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.130–137, одна строка на ноту).- Открыто на владельце: ⚠ НОВОЕ 06.09: второй круг селф-ревью — бэкенд-сессия передала слово владельца «после сдачи обязателен селф-ревью, и если он дал исправления — НОВЫЙ круг, проверяющий исполнением и исходный заказ, и закрытие находок предыдущего круга». Первую половину того же слова (комментарии) он подтвердил как РЕКОМЕНДАЦИЮ, про вторую не сказал ничего; в мандате самопроверки
CLAUDE.mdсегодня описан ОДИН круг. Сессии исполняют добровольно, каноном не стало. ⭐ УЛИКА В ПОЛЬЗУ ПРАВИЛА, снятая в ту же ночь 07.09: круг 2 бэкенд-сессии опроверг ЕЁ ЖЕ правку круга 1 — свёртка сравнения черезNormalizeSourceKeyвводила ЛОЖНООТРИЦАНИЕ (замер зоны:ReplaceGlossary(族長 + 族长)→rows stored=2, контроль на байт-равномsrc→UNIQUE 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.136–145, здесь не держатся.- Сделано (сводно) — снимок ленты закрытых эр в archive/PROGRESS-2026-08-04-09.md; детали — D-лог и слайсы.
- ⭐ КУРС НА 04.09 — ПОРЯДОК РАБОТ, СОБРАННЫЙ ВЕЕРОМ ПО ВСЕМУ БЭКЛОГУ (31 агент, 46 кандидатов, шесть срезов + опровергатели + критик полноты). ⚠ Главный результат метода, а не списка: из 46 кандидатов бэклога опровержение пережили ДВА — остальное трекерная инерция; а то, чего в трекере не было ВОВСЕ, оказалось тяжелее всего, что в нём есть (строки 269–275, заведены этим же заходом). Порядок: (1) ЭКСПЛУАТАЦИЯ — ✅ ЗАКРЫТА ЛЕНДИНГОМ 05.09 (
7e2226a+3e84716, акт D39.201): бэкапы с ПРЕДЪЯВЛЕННЫМ восстановлением, дверь для не-браузерного клиента, имя книги. Строки 269 · 270 · 274 закрыты и сняты из таблицы; ниже — история заказа. Строка 269 бэкапов нет ни у оплаченной работы, ни у денежного реестра — ЕДИНСТВЕННАЯ находка дня без частичного исхода: одна потеря диска необратима и недоказуема · строка 270 у продукта НОЛЬ дверей:bearerTokenобъявлен и не выдаётся, живой цикл 04.09 прошёл через dev-вход, который прод отказывается запускать, фронт заморожен · строка 274 имя книги в выданном файле исходноязычное и не чинится ничем (дёшево, а ломается первое, что видит человек). (2) ДЕНЬГИ И ЕДИНИЦА ЗАКАЗА — РЕШЕНО 04.09 во ВТОРОЙ редакции, строки 276–283: заказ это ОБЪЁМ, объём меряется ЗНАКАМИ ИСХОДНИКА ПО ЮНИТУ (движок публикует в манифесте), «страница» — их отображение и её размер это ДАННЫЕ ЛОКАЛИ; вердикт ДО клика, сумму человек не выбирает. ⚠ Первая редакция мерила ГЛАВАМИ и пала: глава надёжна в одном случае из трёх, дыру нашёл владелец. ⚠ Тем же вопросом вскрыта ВТОРАЯ ненадёжная единица —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.59–123). Хвосты курса живут строками: 16 (полная цена холодного старта; edit-волна на малых прогонах отработала и оплачена — 58 вызовов волновым драйвером 23–25.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: разморозка ничего не разблокирует, пока идут доработки) · веса K1–K12 (13а: веса не нужны, мерить по узлам) · вне-претрейн чекпоинт (55: прогоняем на тех же текстах, оговорка — ограничение ВЫВОДА, а не требование новой книги) → ВТОРАЯ ПАРА живьём (ja→ru; преп 81) → МАСШТАБ → пилот Ф2.5 (гейт резюме-строки 80; строки 62–68, 85) → Ф3 ридер-IDE (69–71). Стоячие: 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 держать как июльское. ⚠ Вендор-факты 13–15.08 (пере-пин ИСПОЛНЕН и ПРИНЯТ, D39.137): таблица цен запинена ПИКОМ (flash 0.44/1.32 · pro 1.32/3.96/кэш-хит 0.044 за 1M; счёт шиппинг-c1 = 100% DeepSeek ⇒ ×4.2–4.4 в пике / ×2.1–2.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 сb8154cd—enabled: 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(стройка паков 11–16, rerun2) ·-25-31(паки 17–20 · мини-прогон · полигон-пакеты 5–8 · ToS · холодный прогон; D39.26–58) ·-08-01-02(сессии №9/№10: общность · качество банка · coldrun-b · открытие фронта/платформы; D39.59–90, срез D39.105) ·-08-02-04(сессии №11–№13: ручки эффорта · стандарты · контракт API · платформа P0 · банк-арбитраж; D39.91–105 + снимок шапки эры №15) ·-08-04-09(пинги закрытых паков эры №15) ·-08-14-15(закрытые бэкенд-записи №16–17: эмиттер шва · 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 ЗАКРЫТЫ и сняты из таблицы, найденное вне карты отчёта заведено строками 287–290. ⚠ Эррата 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двигаетEmbeddedVersion→cutTag(докстринг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 — после шагов 0–1 полигона (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:
Ресёрч-сессия ЗАКРЫТО 04.09. Оба отчёта топологии заленджены полигоном на СВОЕЙ ветке по прямому указанию владельца (textmachine-36 — лендинг research/29a7951a7) и приехали в 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 и полоса 10–19), глаголов 6 против 11, mined_delta/mined_rejects
как ключи book.yaml (RETIRED, валят загрузку), машинная .bank-stop.json (снесена D39.158),
Adult bool. В заголовке обоих — «синхронизировано с D1–D39.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:16 («internal/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», тело цитирует ноты 23–28.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; здесь копий нет.)
Бэкенд
Пак «гейт вместо прозы» (07.09, промт docs/BACKEND_GATES_NOT_PROSE_SESSION_PROMPT.md, вход HEAD bd652fd). НЕ КОММИЧУ — ждёт лендинга
ЗАПИСКА-ПЛАН (§7), написана ДО первой правки. Пять швов держатся прозой и вырожденными фикстурами; ставлю под каждый гейт, боевой код трогаю ровно в одном месте (§4.2а — единственная заказанная смена поведения).
Порядок и довод порядка. (1) §4.1 шов заголовка — самый определённый и самый дорогой по последствиям (под M2 книга выходит с «1», «2» вместо названий глав), и его фикстура нужна раньше остальных, потому что на ней же стоит §4.4. (2) §4.2 порядок предвычисления — три части одной работы, и (в) гейт каталога обязан подхватить записи из (1) и (б). (3) §4.4 два теста ингест↔чанкер — тот же пакет chunk, что и (1). (4) §4.3 линт словаря классификатора. (5) §4.5 армы — последний, потому что он один умеет сдвинуть байты меток промтов, и его последствия видны только на полной батарее. (6) §4.6 попутные — по факту открытых файлов.
Что считаю рискованным в этом паке — поимённо, до работы.
- §4.2(а) снапшот-нейтральность. Единственное место, где пак может нарушить обещание §1. Форма аддитивная (отдельная секция сайдкара, глоссарий не трогается), доказательство — байт-равенство снапшота обеих волн до и после; неравенство = стоп и пинг, а не «зато артефакт непустой».
- §4.1 невырожденность моей же новой фикстуры. Тот дефект, который пак чинит, — типовое место, где прячется второе вырождение. Мерило задано промтом: ≥2 edit-юнита в главе, иначе M1 тождественен боевому коду и переживёт новый тест. Числа печатаю оба (чанков на главу и юнитов на главу) и утверждаю их В ТЕСТЕ, чтобы будущая смена бюджета роняла тест, а не тихо вырождала его.
- §4.5 сдвиг меток промтов. Пере-снятый арм почти наверняка двинет байты
testdata/prompt-labels.json. Сначала смотрю, ЧТО сдвинулось и следствие ли это заказанной правки, и только потом обновляю леджер; обновление объявляю отдельным пунктом отчёта. - §4.2(в) пять способов получить зелёный гейт, ничего не проверивший (список в промте). Мой ответ на каждый — в отчёте по этому пункту.
Замер входа, снятый МНОЙ, а не унаследованный. Дерево на входе чисто: git status --short — 0 строк при HEAD bd652fd (контроль: тот же вызов минутой раньше, на HEAD d3eb56b, печатал 2 строки — модифицированный docs/CHAPTER_STRUCTURE_DESIGN_SESSION_PROMPT.md и неотслеживаемый файл моего промта; оба уехали в bd652fd/d3eb56b). Копия дерева для мутаций снята в скретчпад, контроль diff -rq рабочее↔копия — 0 строк расхождения. ⚠ Форма копии тогда была cp -a; круги 2–4 показали, что она уносит .env, и заменили её на tar с исключениями — см. круги ниже.
Форма фикстуры §4.1 найдена ЗАМЕРОМ, не подбором. Пробой на копии (SegBudget{DraftBudgetOut:1797, EditCeilingOut:3200, FertCJK:1.1978}) перебраны главы из 2/3/4/5/6 абзацев по 900 рун: 2 абзаца → 2 чанка / 1 юнит, 3 → 3 чанка / 1 юнит, 4 → 4 чанка / 2 юнита, 5 → 5/2, 6 → 6/2. ⇒ порог именно 4 абзаца, и главы из трёх чанков НЕДОСТАТОЧНО: i == 0 там совпадает с ChunkIdx == 0. Беру 4: юнит 0 держит чанки 0–2, юнит 1 — чанк 3, то есть фикстура упражняет ОБА различения сразу — «не-первый чанк внутри того же юнита» и «первый чанк НЕ-первого юнита».
ИТОГ: пять швов, которые держались прозой и вырожденными фикстурами, закрыты гейтами; боевой код тронут ровно в одном заказанном месте (§4.2а), и снапшот-нейтральность этого места доказана байт-равенством, а не формой правки. Каталог мутаций 211 → 222 записи, из них 11 помечены как подмножество, которое реально ГОНЯЕТСЯ (make mutations) — до этого пака зелень каталога означала «посадка на месте», а не «посадка краснит» (строка 313).
Исход по КАЖДОМУ пункту §4 — пунктов без исхода нет
| пункт | исход | чем предъявлено |
|---|---|---|
| §4.1(а) невырожденные фикстуры | СДЕЛАНО, обе | chunker_heading_test.go печатает «8 chunks; chunks per chapter map[1:4 2:4]; edit units per chapter map[1:2 2:2]; chunks carrying a title 2»; contractblockers_test.go — «8 chunks in 2 chapters; chapter 1 = 2 units; titles "Глава 1"/"Глава 2"». Оба числа УТВЕРЖДАЮТСЯ, а не логируются: chunksPer[ch] < 2 || unitsPer[ch] < 2 → t.Fatalf |
| §4.1(а-строгое) ≥2 edit-юнита | СДЕЛАНО | форма фикстуры найдена ЗАМЕРОМ (см. записку-план): 3 абзаца дают 3 чанка / 1 юнит, 4 абзаца — 4 чанка / 2 юнита. Взято 4: юнит 0 держит чанки 0–2, юнит 1 — чанк 3 |
| §4.1(б) утверждение о не-первом чанке | СДЕЛАНО, с обеих сторон шва | на разрезе — цикл по всем чанкам в TestSplitChunksHeadingCarried; на реконструкции — отдельное утверждение в TestManifestChunksReproduceTheCut, доказанно НЕ холостое (см. ниже) |
| §4.1 M3 (экспорт) | СДЕЛАНО | новый TestExportCarriesTheChapterTitleOnTheUnitThatOpensTheChapter: «export: 4 units, leading unit holds 3 chunks, 2 of them carry a title» + утверждение, что FinalText начинается заголовком |
| §4.1(в) M1·M2·M3·M5 в каталог | СДЕЛАНО, 4 записи | все четыре КРАСНЫЕ, тексты падения в таблице мутаций |
| §4.2(а) строка 224 | СДЕЛАНО аддитивно | секция proposed в сайдкаре; TestBankStopPublishesItsProposalsInTheReadOut; глоссарий не тронут — тест утверждает total=1 signed=1 (сид) и отсутствие 方源 в terms |
| §4.2(а) снапшот-нейтральность | ДОКАЗАНА исполнением | capture.golden пере-снят на дереве HEAD и на моём: один и тот же sha256 c1577859…, 0 строк расхождения при 252 строках файла; КОНТРОЛЬ — заведомо сдвинутый chunkerVersion даёт 196 строк расхождения и другой snapshot_draft |
| §4.2(б) мутации порядка | СДЕЛАНО, 2 записи | bookrun.go (0 записей из 211 до пака) и mining.go — обе красные с адресным текстом |
| §4.2(в) подмножество в гейт | СДЕЛАНО, форма выбрана и аргументирована | см. отдельный раздел ниже |
| §4.3 линт словаря | СДЕЛАНО | classifiervocab_test.go в internal/pipeline; печатает «classifier prompts linted: 1; vocabulary asserted: [name place term title female male neuter none]»; отрицательный кейс — В ТЕСТЕ |
§4.3 bankTypeOK |
СДЕЛАНО | снят; оба места читают terminology.CandidateTypes. Контроль: носителей множества в прод-коде осталось 1 (classify.go:26) |
| §4.4 (A) паритет | СДЕЛАНО | TestIngestAndChunkerAgreeOnOrdinaryChapterHeaders — предикаты + сквозной IngestEncoded→SplitChunks |
| §4.4 (B) пин расхождения | СДЕЛАНО, все четыре стороны | TestIngestAndChunkerDivergeOnAZeroPrologueAndALongHeader; переворачивается на посаженном БУДУЩЕМ фиксе (предъявлено исполнением) |
| §4.5 пере-снятие армов | СДЕЛАНО, 2 арма | не-комментарных строк расхождения арма с c1: было 24/24, стало 3 (ровно блок редактора). Контроль: c1 против себя = 0 |
| §4.5 гейт равенства | СДЕЛАНО, форма — структурное сравнение | config.TestAnArmIsTheProductionConfigWithADifferentEditor; на ДО-паковом арме краснеет тремя блоками: Stages, Gates, Mining |
| §4.5 судьба deepseek-pro | НАЗВАНА: файл СНЯТ | довод и перенос гарантии — раздел ниже |
| §4.6 строка 349 (а)(б)(в) | ВЗЯТО | правки на месте |
| §4.6 строка 350 | ВЗЯТО: шесть функций РЕШЕНЫ (все шесть — «оставить, причина названа на месте»), инлайн свёрнут | замер вызовов ниже |
| §4.7 чего в паке нет | НЕ ДЕЛАЛ | фикс 第零章 не тронут; chunkerVersion не двигался (доказано голденом) |
⛔ ПОПРАВКА К ФОРМУЛИРОВКЕ «единственная заказанная смена поведения — §4.2(а)»: их ДВЕ, и вторая денежная. Она верна для боевых c1/c2 и НЕВЕРНА для армов. Пере-снятие (§4.5) дало обоим живым армам банковый контур целиком: prompt_override: ../prompts/zh-ru/translator-banknote.md с лейблом v2-reflow-nogenre-banknote, mining.contrast_path, gates.banknote.enabled: true, gates.terminology.enabled: true с budget_usd: 1.00 и classify_budget_usd: 1.00 (git diff --numstat: glm 37 вставок / 29 удалений, mistral 43 / 31 — столбец --stat «66» и «74» это их СУММА, а не вставки). ⇒ прогон по арму теперь ПОКУПАЕТ банковый контур, которого раньше не покупал, и оба его волновых снапшота сдвинуты (четыре хеша — в круге 2, находка 8). Оплаченных книг это не касается: на арм-файлы репозитория не пиннута ни одна (контроль: 0 строк pipeline: на backend/configs/pipeline-arm-* при 124 живых ссылках на backend/configs/), деплой прибит к боевому. Но это ЗАКАЗАННАЯ строкой 348 смена, а не побочный эффект, и лендинг-нота обязана назвать её отдельно — иначе следующая смена прочтёт «единственная смена — сайдкар» и поставит на этом замер.
Таблица мутаций — правая колонка это ТЕКСТ падения, а не факт красноты
| мутация (id каталога) | где посажена | какой тест покраснел | ТЕКСТ падения |
|---|---|---|---|
TITLE-cut-puts-the-heading-on-the-chapters-first-chunk (M5) |
chunk/chunker.go — заголовок на ПОСЛЕДНИЙ чанк главы |
TestSplitChunksHeadingCarried |
«chapter 1 chunk 0 (edit unit 0) heading = "", want "Глава 1"» и «chapter 1 chunk 3 (edit unit 1) heading = "Глава 1", want ""» |
TITLE-heading-belongs-to-the-chapter-not-the-edit-unit (M1) |
pipeline/manifest.go — ChunkIdx == 0 → i == 0 |
TestManifestChunksReproduceTheCut, TestExportCarriesTheChapterTitle… |
«chunk 3 differs — manifest{chapter 1, chunk 3, unit 1, title "Глава 1"} vs cut{… title ""}» и «exported chapter 1 unit at chunk 3: heading = "Глава 1", want ""» |
TITLE-manifest-restores-the-heading-at-all (M2) |
pipeline/manifest.go — if false |
те же два | «chunk 0 differs — manifest{… title ""} vs cut{… title "Глава 1"}» и «exported chapter 1 unit at chunk 0: heading = "", want "Глава 1"» |
TITLE-export-reads-the-units-leader (M3) |
pipeline/export.go — Members[0] → Members[len-1] |
TestExportCarriesTheChapterTitle… |
«exported chapter 1 unit at chunk 0: heading = "", want "Глава 1" — a chapter's title belongs to the unit that OPENS it» |
ORDER-the-bank-is-published-after-it-is-seeded |
pipeline/bookrun.go — exportBank("run-start/seeded") ПЕРЕД seedGlossary |
TestTheRunStartReadOutAlreadyCarriesTheSeededBank |
«the run-start read-out carries total=0 signed=0, want the seeded row — the bank was published before it was materialised» |
ORDER-the-stop-holds-its-rows-before-it-publishes-them |
pipeline/mining.go — экспорт ПЕРЕД r.lastBankStopRows = rows |
TestBankStopPublishesItsProposalsInTheReadOut |
«the read-out published NO proposals while the stop presented 3 — this is the row-224 defect itself» |
BANKSTOP-proposals-reach-the-read-out |
pipeline/bankexport.go — снята публикация секции |
тот же | тот же текст |
HEADING-ingest-and-chunker-answer-the-same-on-an-ordinary-header |
chunk/ingest.go — chapterHeaderMaxRunes 60 → 6 |
TestIngestAndChunkerAgreeOnOrdinaryChapterHeaders + 5 прежних |
«the ingest cut 2 chapters out of 3 headers» |
CLASSVOCAB-a-class-the-engine-keeps-must-be-named-in-the-pair-prompt |
terminology/classify.go — в Types добавлен класс artifact |
TestEveryClassifierPromptSpeaksTheEnginesVocabulary |
«../../prompts/zh-ru/classifier.md never names [artifact] where the model can see it» |
Выживших нет: 14 записей, 14 RED, 0 unexpected outcome(s), выход 0; гниль якорей всего каталога — anchors swept: 0 of 225 entr(ies) rotten. ⚠ Девять строк таблицы выше — состав на круг 8; пять записей дофикса ниже отдельным блоком, с тем же требованием к правой колонке.
Пять записей ДОФИКСА — тот же формат; тексты сняты -logs на копии (5/5 RED, 0 unexpected outcome(s), 1m38.4s, anchors swept: 0 of 225).
| мутация (id каталога) | где посажена | какой тест покраснел | ТЕКСТ падения |
|---|---|---|---|
TITLE-the-number-in-a-title-is-the-headers-not-the-ordinals |
pipeline/manifest.go — заголовок ре-деривируется из ординала: ch.Heading = "Глава " + strconv.Itoa(...) |
TestTheBuiltBookCarriesChapterTitlesAndNotTheirNumbers, TestManifestChunksReproduceTheCut, TestExportCarriesTheChapterTitleOnTheUnitThatOpensTheChapter |
«chunk 4 differs — manifest{chapter 2, chunk 0, unit 2, title "Глава 2"} vs cut{chapter 2, chunk 0, unit 2, title "Глава 3"}». Мутация переживает ЛЮБУЮ фикстуру, где ординал совпадает с номиналом — её ловит только невырожденная (номиналы 1 и 3) |
TITLE-the-built-book-carries-names-not-numbers |
pipeline/export.go — ce.Heading = "" |
TestTheBuiltBookCarriesChapterTitlesAndNotTheirNumbers, TestExportCarriesTheChapterTitleOnTheUnitThatOpensTheChapter |
«the built book has no chapter titled "Глава 1" — assembleBook substitutes the chapter NUMBER when the export carries none, which is exactly how a book ships as «1», «2»» — тот самый симптом, с которого пак начинался |
TITLE-the-glued-heading-is-stripped-from-the-body |
pipeline/bookbuild.go — снят strings.TrimPrefix(text, ce.Heading+"\n\n") |
TestTheBuiltBookCarriesChapterTitlesAndNotTheirNumbers, TestAssembleBookMarksEveryHoleKind |
«"Глава 1" appears 2 times in the built book, want 1 — the heading prefix is not being stripped from the body it was glued onto» |
ARM-an-arm-is-the-production-config-with-a-different-editor |
configs/pipeline-arm-glm.yaml — снята строка cache_ttl: "5m" |
TestAnArmIsTheProductionConfigWithADifferentEditor/pipeline-arm-glm.yaml |
«pipeline-arm-glm.yaml is not pipeline-c1.yaml with a different editor — Context differs: c1 = {GlossaryInjection:selective GlossaryTokenBudget:800 CacheTTL:5m}, arm = {... CacheTTL:}». ⚠ Первая посадка краснела НЕ ТЕМ механизмом — отказывал загрузчик, до сравнения дело не доходило; пере-сажена на ключ, которого загрузчик не требует |
BANKSTOP-proposals-belong-to-a-stop-and-to-no-other-boundary |
pipeline/mining.go — r.lastBankStopRows = rows в ветке авто-продолжения |
TestBankStopDefaultIsAutoContinue |
«the read-out carries 3 proposal(s) after an AUTO-CONTINUE — that section is a signature stop's, and this run did not stop» |
Сверх каталога — три посадки, предъявленные исполнением на копиях и НЕ занесённые в каталог (по разным причинам, названным здесь же):
- Будущий фикс строки 346 (
parseSectionNumeral:v <= 0→v < 0, то есть нулевая секция принимается). Посажен на копии;TestIngestAndChunkerDivergeOnAZeroPrologueAndALongHeaderпокраснел текстом «the prologue now carries the title "Глава 0" — the divergence backlog row 346 pins has CLOSED — that is the fix landing, not a regression. Delete this test and fold the case into TestIngestAndChunkerAgree…», а паритетный тест остался ЗЕЛЁНЫМ. Это и есть контракт пары тестов, предъявленный целиком. В каталог не занесён намеренно: каталог описывает ДЕФЕКТЫ, а это заказанная будущая правка. - Снятие поэлементного сравнения в
TestManifestChunksReproduceTheCut(проверка МОЕГО нового утверждения на холостой ход). На копии сравнение убрано, затем посажены M1 и M2 — оба покраснели МОИМ утверждением: «reconstructed chapter 1 chunk 3 (edit unit 1) heading = "Глава 1", want "" — the read path puts a chapter's title on its FIRST chunk only». Утверждение стоит само. - Возврат до-пакового
pipeline-arm-glm.yamlиз HEAD против нового гейта равенства: три блока названы поимённо —Stages(у арма нетprompt_overrideбанкнотного переводчика),Gates(Banknote.Enabled:false, весьTerminologyнулевой),Mining(ContrastPath:пуст).
§4.2(в) — форма гейта каталога: решение и довод
Решение: подмножество живёт СОСЕДНЕЙ целью make mutations, а не внутри battery. Довод — числами, а не вкусом:
make batteryцеликом: 2 мин 55 с (exit 0,0 issuesлинта, 19ok/ 0FAIL).make mutations(11 записей): 3 мин 3 с (exit 0, 11 RED, 0 unexpected, гниль каталога 0).
⚠ Обе цифры — состав ДО дофикса (11 записей). После дофикса состав 14, и пара пере-снята ОДНИМ прогоном каждая: батарея 3 мин 14 с, мутационная цель 3 мин 59,7 с — это 123 %, то есть ВЫШЕ диапазона 87–104 %, который дали девять до-дофиксных пар. Одна пара диапазона не задаёт, но направление однозначно: три новые записи цель удлинили, и решение «соседней целью» дофикс укрепил — внутри battery подмножество удвоило бы её время. ⚠⚠ ПОПРАВКА 08.09: числу «123 %» веры нет, и я его отзываю. Парный замер спина-к-спине дал 102 %, то есть мои 123 % были фоновой нагрузкой машины, а не свойством цели. Верное утверждение — «стоит примерно столько же, сколько батарея»; любая цифра точнее разъезжается от загрузки шире, чем цели отличаются друг от друга. Носитель в backend/README.md пере-снят той же формулировкой.
Довод «внутрь battery» звучит сильно — гейт, который никто не зовёт, воспроизводит дефект строки 313 на шаг выше. Отношение замерено на девяти прогонах и это ДИАПАЗОН, а не одна пара: мутационная цель стоит 87–104 % времени всей батареи (крайние пары 2:42/3:06 и 3:03/2:55). Брать край как довод нельзя — беру диапазон — то есть внутрь она не «добавилась бы», а почти удвоила бы каждый прогон. Он проигрывает этому и ещё одному факту: tmmutate гоняет пакет БЕЗ -race, то есть доказывает МЕНЬШЕ, чем цель test, а стоит от неё заметную долю. Класть внутрь battery более слабый по гарантиям прогон ценой такого прироста — плохой размен на цели, которую сессии зовут по десять раз в день. Соседняя цель названа в Makefile рядом с battery, стоит одной строки в промте следующей смены и не удорожает каждый прогон.
⚠ Это моё решение, и у него есть цена, которую я называю прямо: соседняя цель может остаться незваной, и тогда дефект строки 313 просто переедет на уровень выше. Если оркестратор считает, что размен другой, — это правка одной строки: battery: build vet fmt lint test mutations.
Пять ловушек §4.2(в) — ответ по каждой:
- Список
-idруками в Makefile. Не сделано: состав ВЫВОДИТСЯ из каталога полемbatteryзаписи (cmd/tmmutate/main.go, флаг-battery). ВMakefileслова-idнет. Пустое подмножество — не зелень, а отказ: «the catalogue marks no entrybattery, so the battery subset is empty; a gate with no members proves nothing». expect: "survives"как дверь для подгонки. Закрыта СТРУКТУРНО, а не дисциплиной: валидатор каталога отказывает наbattery && expect=="survives"— «an entry with expect "survives" cannot be in the battery subset — it would make the gate green by NOT being caught». Контроль: записей сbattery=true— 14, из нихexpect=survives— 0.git archive HEADвместо копии рабочего дерева. Цель копирует РАБОЧЕЕ дерево; иначе гейт судил бы HEAD и моих новых пинов не видел. ⚠ Форма копии сменилась дважды по ходу кругов и сейчас такова:tar -cf … --exclude=./bin --exclude='./.env*'с якорем на каталог самогоMakefile, две команды через&&(конвейер терял статус источника), копия вmktemp -d, уборкаtrap … EXIT INT TERM— то есть и на падении. Секреты в копию НЕ пишутся вовсе, а не удаляются из неё вторым шагом.Package— пакет ПИНА, а не правки. Соблюдено и предъявлено двумя записями:TITLE-cut-puts-the-heading…правитinternal/chunkи судится./internal/chunk/(пин там же), аCLASSVOCAB-…правитinternal/terminology, но судится./internal/pipeline/— потому что каноническая форма промта реализована там. Запись с чужим пакетом честно сказала бы SURVIVED.- Время — СУММА по записям. Названо числом ниже, в разделе замеров. ⚠ В первой редакции этого отчёта разбивка была НЕВЕРНА — я написала «8 в pipeline + 1 в chunk», нашёл круг 2: их 8 и 2. Сегодня записей 10 (
./internal/pipeline/≈ 17 с на запись,./internal/chunk/≈ 0.1 с, плюс по одному базлайну на пакет).
«Выживший мутант красит выход» — предъявлено ИСПОЛНЕНИЕМ, а не объявлено. На копии в подмножество внесена заведомо выживающая запись (правка комментария, которую поймать нечем): SURVIVED ZZ-SURVIVOR-PROBE, 1 mutation(s) run, 1 unexpected outcome(s), tmmutate: not what the catalogue records, make: *** [mutations] Error 1, EXIT=2. Там же проверена уборка на ПАДАЮЩЕМ пути: каталогов /tmp/tmp.* после падения — 0 (контроль: mktemp -d создаёт именно такое имя — проверено вызовом), а исходник в копии восстановлен (якорь комментария на месте, 1 вхождение).
⚠ И вслух, как требует промт: инструмент гоняет пакет БЕЗ -race. Он доказывает «этот пин ловит эту посадку», а не «пакет чист под гонками» — это остаётся за целью test.
§4.5 — судьба pipeline-arm-deepseek-pro.yaml: файл СНЯТ, и вот куда уехали его гарантии
Решение: снять. Довод, и он не «так чище»: после честного пере-снятия арм совпал бы с pipeline-c1.yaml целиком — редактор боевого с D39.22 это и есть deepseek-v4-pro + few_shot: false. Арм существует, чтобы изолировать ОДНУ переменную; этот не изолировал ни одной. Решающий довод — третий, и он про класс, который пак закрывает: пока файл жив, TestSwapArmConfigs пиннул редактора БОЕВОГО конфига под именем АРМА, и законный флип интерим-редактора (D39.22 прямо называет выбор интеримом) ронял бы тест, который в тексте падения говорит «арм неверен», когда уехал c1. Это ровно та форма, где правый вердикт приходит по неправой причине.
Куда уехали гарантии, которые держал только этот файл:
| гарантия | где была | где теперь |
|---|---|---|
few_shot: false у reasoning-редактора |
TestSwapArmConfigs, ветка fewShotOff (пиннула АРМ) |
цикл по pipeline-c1.yaml + pipeline-c2.yaml в том же файле — теперь пиннуты конфиги, которые это РЕАЛЬНО везут |
| «арм не пере-вооружает эхо-мину» | арм-строка | остальные два арма, строка не тронута |
| «арм == боевой вне редактора» | нигде (шапка обещала, тест не проверял) | новый TestAnArmIsTheProductionConfigWithADifferentEditor |
| «арм, совпавший с боевым, — не арм» | нигде | тот же гейт: отдельное утверждение, которое краснеет ровно на этом состоянии |
Снято 7 упоминаний файла (счёт по диффу): пять — списки шиппинг-конфигов (config/echoregen_shipping_test.go ×1, config/content_labels_test.go ×2, config/prompt_pack_test.go ×1, pipeline/promptlabel_test.go ×1), шестое — строка таблицы TestSwapArmConfigs, седьмое — ссылка в комментарии pipeline-c1.yaml. Комментарии pipeline-c1.yaml и pipeline-c2.yaml, ссылавшиеся на «dspro-арм», пере-написаны: иначе в дереве осталось бы имя, которое ни во что не разрешается (класс строки 299).
⚠ Предсказание промта про сдвиг байтов меток промтов НЕ ПОДТВЕРДИЛОСЬ, и я проверила ПОЧЕМУ, прежде чем что-либо обновлять. TestPromptLabelsPinTheirBytes зелен БЕЗ единого касания testdata/prompt-labels.json; леджер в дереве не изменён. Причина механическая: пере-снятый арм действительно получил prompt_override банкнотного переводчика, но ключ zh-ru/translator/v2-reflow-nogenre-banknote уже claim'ил pipeline-c1.yaml, а осиротевший было ключ zh-ru/translator/v2-reflow-nogenre claim'ит pipeline-c2.yaml (контроль: греп по configs/*.yaml даёт ровно одно вхождение этого лейбла — pipeline-c2.yaml:29). Множество ключей не изменилось ⇒ обновлять нечего. Это важно назвать вслух: сторож осиротевших ключей в этом тесте живой и покраснел бы, если бы claim пропал. Никакого TM_UPDATE_PROMPT_LABELS=1 я не запускала.
§4.6 — попутные: что взято и с каким исходом
Строка 349:
- (а)
snapshotdiff.goдописывал оператору причину, которой не проверял («the auto-bank grew between purchases»). Утверждение снято, осталось то, что функция ЗНАЕТ: «that is the BANK, not a config or prompt edit (what changed in it is in the bank's own history)». В комментарии названо, почему: авто-банк, подписанная владельцем строка, правка сида и реджект двигают ОДНО поле, а функция видит хеш против хеша. - (б) Протухшие клаузы про «последовательный драйвер» сняты в
snapshot.go(две) иwave.go(две — тот же класс, нашла попутно). Контроль: вхождений «sequential driver/runner» вbackend/internal/**/*.goбыло 5 (snapshot.go ×2, wave.go ×3), стало 1, и то — в новой фразе «the sequential driver this fold was written for no longer exists». ⚠ Заодно ЗАМЕРЕНО и записано в комментарий: уRunner.snapshotID()ноль прод-вызовов (5 тестовых). Он не удалён — это вне заказа — но читатель больше не примет его за живой путь. - (в)
backend/README.mdназывалstatus.goread-only проекцией. Поправлено с указанием пути:Runner.Redrive→Store.ResetChunkStages— единственный деструктивный путь движка.
Строка 350 — шесть функций, исход по КАЖДОЙ, и он у всех шести один: ОСТАВИТЬ, причина названа на месте. Замер вызовов (не по имени, а по квалифицированному вызову; контроль — chunk.SplitChunks = 12 живых вызовов):
| функция | вызовов | что найдено | исход |
|---|---|---|---|
obs.SafeGo |
0 (1 упоминание — комментарий waverun.go:405 «NOT obs.SafeGo») |
намеренный КОНТРАСТ: там recover обязан уронить прогон | оставлена, к определению добавлено, что вызова нет и почему; удаление повесило бы тот комментарий в воздух |
text.TokenizeCyrillic |
0 (2 упоминания — checks/sanitizer.go:21 и :197) |
образец паттерна value-default, на который дважды ссылаются по имени | оставлена; ⚠ её прежняя дока УТВЕРЖДАЛА «serves callers that are unconditionally Russian», которых ноль — формулировка исправлена |
CheapGateResult.UnitScaleHard |
0 | поверхность контракта Р2, ждёт строку 12 — причина уже стояла | оставлена, дописан факт «вызова нет» |
CheapGateResult.UnitScaleSoft |
0 | то же | то же |
Bank.Voices() |
0 | read-сторона состояния, которое банк и так грузит; потребителя держит строка 13б | оставлена, причина названа на месте |
Bank.Pairs() |
0 | то же | то же |
Словарь родов — четвёртый пункт строки 350, и он оказался НЕ про «четыре носителя», а про врущий текст. Замер: membank/memseed.go:600 принимает восемь значений — "" · male · m · female · f · neuter · n · hidden, — а текст его собственной ошибки (:618) говорил «is not one of male|female|neuter|hidden», то есть НЕ называл короткие формы m/f/n, которые принимает. Предъявлено исполнением: gender="m" ПРИНЯТ (нарушения нет), а читатель ошибки заключил бы обратное. Лечение — вывести перечень из самой карты (knownGenderNames()), а не писать рядом второй копией; после правки сообщение: gender "Male" is not one of f|female|hidden|m|male|n|neuter (empty means no gender datum). Остальные три носителя (membank/memory.go:957, terminology/classify.go:50, промт) НЕ трогала: terminology.Genders — намеренное ПОДМНОЖЕСТВО без hidden, и его довод стоит на месте в доке (hidden — решение о сюжете, а не наблюдение по контекстам).
Инлайн «последняя стадия». ⚠ Строка 350 здесь неточна, и это стоит поправки: «при готовом finalStageWave()» — не тот хелпер. finalStageWave() возвращает ВОЛНУ и уже имеет 10 прод-вызовов (контроль: 10 прод + 3 тестовых = 13, как в строке). Дублировалось же ИМЯ последней стадии — r.Pipeline.Stages[n-1].Name — и готового хелпера для него НЕ было. Заведён finalStageName() рядом с finalStageWave(), оба инлайна свёрнуты (export.go, quality.go). Контроль после правки: вхождений Stages[n-1].Name в internal/pipeline — 1, внутри самого хелпера.
Правки существующих тестов, вызванные ЗАКАЗАННОЙ сменой поведения (D39.183) — объявляю поимённо
TestSwapArmConfigs(internal/config/echo_mine_test.go). Что изменилось в поведении: пак ЗАКАЗАЛ пере-снятие армов и назвал снятиеpipeline-arm-deepseek-pro.yamlодним из двух допустимых исходов. Что тест описывал: три поля арма плюс few-shot-политику. Куда уехала гарантия:few_shot: false— на боевые c1/c2 (см. таблицу выше); полеfewShotOffснято, потому что оба выживших арма несут НЕ-reasoning редактора и оба держат few-shot по дефолту.- Пять списков шиппинг-конфигов — снята строка снятого файла. Гарантии не терялись: списки перечисляют, ЧТО подметать, и файла больше нет.
TestManifestChunksReproduceTheCut— фикстура заменена (ja→ru русская проза через\f→ zh→ru книга с настоящими заголовками). Это не «смена поведения», а лечение вырожденности, ЗАКАЗАННОЕ §4.1(а). Заодно текст падения поэлементного сравнения перестал печатать%+vцелой главы: сравниваются четыре поля, они и названы. Утверждение не ослаблено — сравниваются те же четыре поля.TestSplitChunksHeadingCarried— та же причина, §4.1(а).
КРУГ 2 — адверсариальный проход по СВОЕЙ готовой работе: 18 находок, ВСЕ в моей работе, две блокирующие
Веер: два опуса, один по новым тестам и фикстурам, второй по боевому коду и шиппинг-конфигам. Оба мерили исполнением на своих копиях дерева; рабочее дерево не трогали. Ни одна находка не была снята «по чтению» — каждая либо воспроизведена мной, либо закрыта правкой, чья краснота предъявлена посадкой.
ДВА БЛОКЕРА, оба — дыры в моих же гейтах:
| находка | почему это блокер | что сделано | чем предъявлено |
|---|---|---|---|
Линт словаря читал tpl.FewShot, которого модель НЕ ВИДИТ. Классификатор рендерится MessagesWithInjection (render.go:306-320), а тот берёт tpl.System, НЕ SystemFor(fewShotOn); блок ---FEWSHOT--- на провод этой роли не уходит вообще |
Пак, у которого весь английский словарь лежит в few-shot-блоке, проходил мой линт зелёным, а модель видела только японский. Это ровно тот дефект, который тест объявлял пойманным | Линт сведён к System+User, довод записан у функции. Добавлен ВТОРОЙ отрицательный кейс в тот же тест — пак со словарём только в ---FEWSHOT--- |
Возврат линта к прежней форме на копии → --- FAIL … a pack whose vocabulary lives only in ---FEWSHOT--- was reported to be missing only [] of [name place term title …] |
| Гейт паритета армов сам был СПИСКОМ из двух имён — при том что его собственная шапка запрещает списки («A list is what drifted») | Новый configs/pipeline-arm-*.yaml не проверял НИКТО, включая валидатор загрузчика: ревьюер положил арм без mining.contrast_path — ту самую денежную аварию из шапки теста — и батарея осталась зелёной |
Армы ОБНАРУЖИВАЮТСЯ filepath.Glob, список удалён; пустая выдача — отказ |
С подложенным pipeline-arm-newcomer.yaml: arms discovered: 3 […newcomer.yaml] → --- FAIL … load …: gates.terminology is enabled but mining.contrast_path is not set |
Остальные находки первого ревьюера (тесты):
- Гейт паритета изымал ВЕСЬ стейдж редактора — арм мог разъехаться с боевым по
temperatureиreasoningи остаться зелёным, то есть изолировать три переменные, объявляя одну. Изъятие сужено до МОДЕЛИ (Model/ResolvedModel/EscalateTo/ResolvedHop/FewShot); температура, reasoning, промт и его лейбл теперь СРАВНИВАЮТСЯ. Предъявлено:temperature: 0.4 → 1.9в арме →--- FAIL … Stages differs. loadзамыкал ВНЕШНИЙt, поэтомуFatalfиз сабтеста валил родителя и следующие армы не проверялись вовсе.tпередаётся параметром. Предъявлено: при сломанном glm-арме--- FAIL …/pipeline-arm-glm.yamlи рядом--- PASS …/pipeline-arm-mistral.yaml— второй арм ПРОВЕРЕН.- Экспорт-тест не покрывал
--pairs— а это единственный режим, который читает ЖИВОЙ раскрой (export.goберётr.bookChunksради колонки исходника), тогда как обычный режим джойнит МАНИФЕСТ. Мутация только чанкера оставляла обычный экспорт правым. Оба режима теперь утверждаются одним хелпером. Предъявлено: посадка «заголовок на лидера каждого юнита» в чанкере →export: … 2 of them carry a title(ЗЕЛЕНО) и следомexport --pairs: chapter 1 unit at chunk 3: heading = "Глава 1", want ""(КРАСНО). - Осиротевший док-комментарий: моя вставка приклеилась к описанию
TestExportGlossaryGateWithheld, и та функция осталась без комментария. Блок возвращён своей функции. - Порядковая вырожденность фикстур заголовка — номер в шапке совпадал с порядковым номером главы (
一·二·三), поэтому «заголовок отрендерен из номера в шапке» и «из счётчика глав» были НЕРАЗЛИЧИМЫ. Класс держался только пином расхождения, который однажды удалят по его же инструкции. Паритетный тест (тот, что переживёт фикс) переведён на непоследовательные номера第一章 · 第三章 · 第七章: теперь глава 2 обязана называться «Глава 3». Предъявлено посадкой «рендерить из счётчика» →chapter 2 (header "第三章 继续") opens with heading "Глава 2", want "Глава 3" — the title must come from the header's own number, not from the chapter counter.
Находки второго ревьюера (боевой код и конфиги):
- ⛔ ПЕРЕ-СНЯТИЕ АРМОВ ДВИГАЕТ ОБА ВОЛНОВЫХ СНАПШОТА АРМ-ПРОГОНА, и я этого в отчёте НЕ НАЗВАЛА. Замерено ревьюером исполнением:
arm-glmdraft4380cb28…→b7151595…, edita6a66f07…→e0b66ee7…;arm-mistraldraft4380cb28…→b7151595…, edit7d9ba0ab…→f7a572b6…; контроль «тот же файл дважды» — moved=false. Механизм:stageSnap.PromptVersion/PromptSHA256(банкнотныйprompt_overrideчерновика) иbanknoteSnapshot()(nil→ненулевой) в обеих волнах. Оба моих прибора смотрели мимо: голден грузитtestdata/golden/pipeline.yaml, а сравнение загруженных значений я делала только по c1/c2. Обещание §1 при этом НЕ нарушено — оно про оплаченные книги, а на арм-файлы репозитория не пиннуто ни одной (контроль ревьюера: 0 строкpipeline:наbackend/configs/pipeline-arm-*при 124 живых ссылках наbackend/configs/; деплой прибит к c1). Но назвать это обязана была я, а не ревьюер. Честный противовес, который тоже стоит записи: флип c1→арм стал ДЕШЕВЛЕ — draft-снапшот арма теперь побайтово равен c1, двигается только edit-волна, ради которой арм и существует; до пака флип двигал обе. - ⛔ Пере-снятые армы больше НЕ КОНСТРУИРУЮТСЯ там, где старые работали: без
configs/mining-contrast.zh.txt(артефакта нет в git по построению)NewRunnerпадает громко, и безlangpack_rootвbook.yaml— тоже. Это КОРРЕКТНОЕ следствие: арм стал настоящей копией боевого, а прежняя «работоспособность» держалась ровно на том, что банковый контур в арме отсутствовал. Но мой пинг поdocs/STACK.mdназывал только денежную половину и писал «(б) закрыто» — теперь названа и механическая: «флип = один арм-конфиг» неверно ещё и потому, что флип требует развернуть артефакт контраста и дать книге langpack. proposedбыл обещан прозой в паке «гейт вместо прозы». Комментарийbankexport.goутверждал «Empty at every boundary that is not a stop», и ни один тест этого не проверял; ревьюер посадил две правки (присваиваниеlastBankStopRowsв ветке авто-продолжения; изобретение строки на не-стоповой границе) — обе прошли зелёными. Закрыто двумя утверждениями и записью каталогаBANKSTOP-proposals-belong-to-a-stop-and-to-no-other-boundary. Предъявлено: посадка A →the read-out carries 3 proposal(s) after an AUTO-CONTINUE; посадка B →the run-start read-out carries 1 proposal(s). Премиса не вырождена: на авто-продолжении печатаетсяtotal=2 signed=0 proposed=0.- Одно слово
origin— два словаря в одном документе.terms[].originэто ПРОВЕНАНС (seed|ruby|mined, платформа переводит вgiven|annotated|found), а моёproposed[].origin— КАНАЛ (mined|banknote|both). Соседний комментарий того же файла аргументирует ровно против этого. Поле переименовано вchannel, пока его никто не читает. - Висящее имя в файле, который отчёт назвал «единственным носителем»:
terminology/classify.go:21ссылался наpipeline.bankTypeOK, снятый этим же паком. Ровно класс строки 299, который я объявляла закрытым для снятого арм-файла. Ссылка пере-написана на живой предмет. - Устаревшее число над урезанным списком:
echoregen_shipping_test.goговорил «the two boevoy cores and the three editor swap-arms» над списком, который тот же пак урезал до двух. Поправлено. make mutationsкопировал.envи удалял его ВТОРЫМ шагом — окно, в котором ключи лежат на диске вне репозитория, а SIGKILL внутри него trap'ом не покрыт. Копия делаетсяtar --exclude=./.env, то есть.envне пишется вовсе. Предъявлено: файлов в копии 432 против 433 в источнике,.envв копии 0 при 1 в источнике. ⚠ Вторая половина этого лечения оказалась ЛОЖНОЙ и исправлена кругом 3 — см. первую строку таблицы ниже:$(CURDIR)не тот якорь, за который я его выдала.pipelineFieldDiffsпаниковал бы на первом неэкспортируемом полеconfig.Pipelineвместо адресного текста. ДобавленCanInterface().- Число в моём же отчёте не сходилось с каталогом: я написала «8 записей в
./internal/pipeline/+ 1 в./internal/chunk/», а было 7 и 2. Исправлено ниже вместе с пере-снятыми числами. - Пар-специфика в шиппинг-конфигах удвоилась:
zh-ru/.zh.в армах было 0/0, стало 2/2 (банкнотныйprompt_overrideиcontrast_path). Это неизбежное следствие того, что арм — копия c1, а перекос признаёт сам c1 (строка бэклога 140); ревью-вопрос «заработает ли пара, которой в репо нет» теперь требует пере-указать три файла вместо одного. Не чиню — это вне заказа, но называю. - Что ревьюеры проверили и НЕ нашли (печатаю, потому что «не нашёл» без предмета неотличимо от «не смотрел»): вырожденных фикстур в новых guard'ах нет — ветка
want == ""реально исполняется,"" == ""нигде; холостых утверждений нет — достижимость каждой новой ветки проверена; полейconfig.Pipeline, которые гейт молча пропускает, нет — все 15 экспортируемые; сценария «мутационный гейт зелёный, ничего не проверив» построить не удалось (exit-статус trap'ом не маскируется — dash 1, bash 1; пустое подмножество иexpect:"survives"отказывают текстом; базлайн-зелень пакета обязательна); секцияproposedНЕ может оказаться непустой вне стопа внутри процесса — присваивание одно, стоп возвращает ошибку, и все три прочие площадки экспорта исполняются строго до майнинга.
Необъявленное следствие процессной локальности, найденное ревьюером и стоящее записи: секция proposed живёт в файле ровно до следующего запуска движка — тот перепишет сайдкар на run-start/seeded уже без неё, а поскольку MarkStopPresented уже пометил поверхности, стоп не повторится и взять секцию будет неоткуда. То есть окно чтения у платформы — от стопа до следующего запуска. Это не дефект моей правки (артефакт всегда был проекцией «как сейчас»), но для платформенной половины строки 224 это условие, а не деталь.
КРУГ 3 — по правкам КРУГА 2: четыре находки, из них одна — регресс от моего же лечения
Круг 3 заказан адресно: в этом проекте лечение предыдущего круга регулярно само становится находкой следующего, и именно так и вышло.
| находка | что это | что сделано | чем предъявлено |
|---|---|---|---|
⛔ Мой комментарий утверждал починку, которой НЕТ. Круг 2 закрыл окно с .env заменой cp -a на tar --exclude, и я написала в Makefile (и продублировала в этом отчёте), что якорь $(CURDIR) закрывает вызов make -f backend/Makefile из корня репозитория. $(CURDIR) — это каталог, ИЗ КОТОРОГО ЗАПУЩЕН make, а не каталог Makefile'а. Пере-снято мной: из корня подставлялось tar -C "…/textmachine", то есть тарился ВЕСЬ репозиторий, а --exclude=./.env якорен к вершине архива и мимо backend/.env промахивался |
регресс не в коде, а в УТВЕРЖДЕНИИ: дефект существовал и при cp -a, но круг 2 объявил его закрытым |
Якорь заменён на каталог самого Makefile'а: MAKEFILE_DIR := $(patsubst %/,%,$(dir $(abspath $(lastword $(MAKEFILE_LIST))))). Комментарий пере-написан: названы и настоящая причина, и то, что остальная часть рецепта по-прежнему требует backend/ рабочим каталогом. Снята и вторая неточность — «world-writable filesystem»: mktemp -d даёт 0700, и старая форма тоже |
make -f backend/Makefile -n mutations ИЗ КОРНЯ подставляет tar -C ".../textmachine/backend"; интегральный замер с этим якорем: .env внутри копии 0 при контроле «.env в источнике: 1», файлов 432 |
Сужение изъятия сделало гейт ЛОЖНО-КРАСНЫМ для законного арма. withoutEditorModel сравнивал ReasoningMaxTokens, а LoadPipeline ТРЕБУЕТ этот ключ на additive-billing провайдере (xAI) — арм на редакторе grok-4.3 не мог ни загрузиться без ключа, ни пройти гейт с ним |
два правила репозитория против друг друга; дыру внёс круг 2 (круг 1, гасивший всю стадию, её не имел) | ReasoningMaxTokens изъят вместе с моделью, с доводом: он не ВЫБРАН, а НАВЯЗАН выбором модели — в отличие от температуры, reasoning и промта, которые остаются сравниваемыми |
подложенный pipeline-arm-grok.yaml: arms discovered: 3, все три PASS; КОНТРОЛЬ — temperature: 0.4→0.7 в том же арме → FAIL … Stages differs |
Непоследовательные номера сделали индексацию headers[c.Chapter-1] небезопасной — тест, написанный ровно на случай «номер поехал», отвечал бы паникой вместо своего сообщения; соседний тест в том же файле объявляет прямо обратное |
замечание, но противоречащее собственной норме файла | добавлена проверка границ с адресным текстом | посадка «счётчик глав ушёл за пределы фикстуры» → the cut produced chapter 7 and the fixture has 3 headers — the chapter counter no longer indexes them (паники нет) |
Утверждение «proposed пусто на run-start/seeded» слабее, чем звучит: к этой границе майнинг ещё не выполнялся, поэтому НИКАКОЕ пере-упорядочивание внутри стопа его не покраснит |
замечание | утверждение оставлено, но его сила названа В КОММЕНТАРИИ: оно ловит проектор, который ИЗОБРЕТАЕТ или переносит строку (это предъявлено посадкой B круга 2), а гейтом от утечки из майнинга работает соседнее — на авто-продолжении | посадка «сайдкар заполняет секцию на каждой границе» → the run-start read-out carries 1 proposal(s); посадка «lastBankStopRows до развилки» этот тест НЕ трогает, и так и записано |
Что круг 3 проверил и НЕ нашёл (печатаю, потому что «регресса нет» без предмета неотличимо от «не смотрел»): линт словаря ничего не потерял — ---FEWSHOT--- нет ни в одном classifier-паке репозитория, а утверждение про провод верно ИМЕННО для классификатора (свёртку SystemFor делает только стадийный путь runner.go, не эта роль); оба отрицательных кейса линта падают по нужной причине при возврате каждой из двух прежних форм. Оба режима экспорта проверяются РАЗНЫМ кодом — мутация в default-ветке и мутация в pairs-ветке дают разные падения. Утверждение на авто-продолжении не вырождено: total=2 при proposed=0. origin→channel не оставил старого имени и читателя не имеет. Содержимое tar-копии эквивалентно cp -a: имена 491 против 491, diff -r --no-dereference идентично, режимы и типы совпадают на всех 491, расходится только mtime (tar пишет целые секунды). Текст ошибки родов совпадает с картой целиком и на пустом значении не возникает вовсе. Развести арм с боевым и остаться зелёным круг 3 не смог: три мутации (contrast_path: "", температура редактора, переименование блока mining:) — все три красные. Полная батарея круга 3 на копии: exit 0, 23 из 23 пакетов.
КРУГ 4 — по правкам КРУГА 3: три находки, и главная — мой обмен одной дыры на другую
| находка | что это | что сделано | чем предъявлено |
|---|---|---|---|
⛔ Круг 3 закрыл ГИПОТЕТИЧЕСКОЕ ложное-красное, открыв РЕАЛЬНОЕ ложное-зелёное. Я изъяла ReasoningMaxTokens из сравнения БЕЗУСЛОВНО, а загрузчик требует его УСЛОВНО — internal/config/pipeline.go:1042-1044, только когда providerReasoning(st.Model) == "additive". На subset-биллинге ключ необязателен и не проверяется, но он РАЗМЕРЯЕТ смету (priceprojection.go, stagerun.go) ⇒ арм мог нести буфер, которого нет у боевого, и остаться зелёным |
ровно тот класс, который шапка этого же файла называет своей первой дырой: «вторая переменная, которую арм изолирует, не сказав об этом» | Изъятие сделано УСЛОВНЫМ: гасится только там, где другое правило это НАВЯЗЫВАЕТ. Условие читает модель из исходного конфига, а не из уже погашенной копии | (а) reasoning_max_tokens: 12345 на glm-5 (subset) → FAIL … Stages differs … ReasoningMaxTokens:12345; (б) арм на grok-4.3 с обязательным ключом → arms discovered: 3, все три PASS. Ложное-зелёное закрыто, ложное-красное не вернулось |
$(abspath …) не разрешает симлинки — дефект круга 2 был в одном симлинке. Makefile, симлинкнутый из корня репозитория, снова заякорил бы копию на корень: замер круга 4 — 1 .env, 2 корневых маркера, 435 файлов в копии |
тихая утечка ключей перед громким падением | realpath вместо abspath |
пять форм вызова (из backend/, -f из корня, -C backend, абсолютный -f, через симлинк на файл) дают один и тот же якорь …/textmachine/backend |
Якорь захватывался на 68 строк ниже места, где появился бы include. $(lastword $(MAKEFILE_LIST)) называет этот файл только до первого include; с include на 13-й строке копия сжималась до 1 файла (контроль: 432 при верном якоре) |
латентно: ключи не текут, но гейт молча перестаёт копировать дерево, ради мутаций которого существует | THIS_MAKEFILE := $(realpath $(lastword $(MAKEFILE_LIST))) захватывается ПЕРВЫМ присваиванием файла |
директив include в файле сегодня 0 (контроль напечатан ревьюером); после правки порядок больше не важен |
Что круг 4 проверил и НЕ нашёл: проверка границ в headingparity_test.go верна и ИСПОЛНЯЕТСЯ (зелёный прогон доходит до headers[2] → «Глава 7», то есть верхний край используется, а не только утверждается); все три клейма пере-написанного комментария про run-start подтверждены исполнением в обе стороны — посадка «проектор изобретает строку» краснит именно эту строку, а посадки «пере-упорядочивание внутри стопа» и «утечка в авто-ветку» её НЕ трогают и ловятся соседями; make -n для build/vet/fmt/lint/test/battery/battery-stand/tools-check побайтово равен HEAD-овскому — ни одна другая цель не сдвинулась; из всего, что «навязано выбором модели», сравниваемым остаётся только LabelModels, и он пуст (map[]) во всех четырёх конфигах.
⚠ Процессная находка не про код, но про мои же промты ревьюерам: я давала всем кругам ОДИН и тот же путь копии, а cp -a src dest в СУЩЕСТВУЮЩИЙ каталог вкладывает, а не заменяет — у одного ревьюера настоящий backend/.env оказался на уровень глубже, чем указывал его же rm -f. Он это заметил и убрал. Контроль сейчас: файлов .env крупнее 100 байт в скретчпаде — 0 (четыре подставных по 7–27 байт, оставленные пробами). Это ровно то окно cp -a + rm -f, о котором предупреждает комментарий в Makefile, — и я воспроизвела его в собственной оснастке.
КРУГ 5 — ВОРКФЛОУ-РЕВЬЮ по осям владельца: 38 находок выдержали, 8 сняты скептиками
Заказ владельца был шире чеклиста: «не воркэраунды · историю зачем так сделано · индустриальные стандарты Go без велосипедов · комментарии только конкретика · дожать до логического конца и исполнить ЗАДУМКУ — техдолг, который мешает СЕЙЧАС, с учётом планов дальше». Воркфлоу: семь линз (задумка · планы перенарезки · Go-стандарты · история и провенанс · воркэраунды · комментарии · необходимость холодного прогона), каждая находка — через трёх независимых скептиков с разными установками (по коду · по заказу · по цене). 146 агентов, 38 находок выдержали, 8 снято.
Класс А — ложные утверждения, которые пак ВНЁС или ПЕРЕ-НАБРАЛ. Все исправлены; каждое опровергалось командой в две секунды, в паке, который называется «гейт вместо прозы».
| # | что было ложно | чем опровергнуто | что стало |
|---|---|---|---|
| A1 | Шапка моего же гейта армов: «платформа берёт плоские $2.00 за банк ⇒ флип на арм выставит счёт за банк, которого никто не майнил» | priceprojection.go bookOnceUSD: if !g.Terminology.Enabled || ContrastPath == "" { return 0 } — до-паковый арм давал 0, а не $2 |
Механизм назван в верную сторону: арм ехал БЕЗ банка, цена книги молча падала, и контур не был ни настроен, ни оплачен. ⚠ Та же ложь ушла моим пингом в docs/STACK.md и уже стоит в строке 348 — пинг исправлен |
| A2 | pipeline-c1.yaml: «лейбл обязан отличаться от конфигов, которые везут ПЛОСКИЙ translator.md (c2 и армы)» |
Клаузу сделало ложной моё же пере-снятие: grep -n prompt_override configs/pipeline-arm-*.yaml → оба везут банкнотный вариант под тем же лейблом |
Названо, что плоский везёт сегодня только c2 |
| A3 | «dspro ×2 дешевле glm» — в pipeline-arm-glm.yaml (я пере-набрала при переписывании шапки) и в pipeline-c1.yaml:95 |
D39.137 п.4, ЖИВОЕ: посылка ПЕРЕВЁРНУТА — в ПИК dspro дороже glm ×1.26, офф-пик дешевле лишь ×1.59, замер на 129 реальных edit-вызовах. Пинг полигона с обоими адресами сдан 30.08 |
Оба носителя правлены: факт назван, ратификация жильца объявлена открытой, а не пере-решена мной |
| A4 | Мой комментарий у snapshotID(): «переживает как эталон, с которым тесты сверяют волновые фолды — сумма которых он и есть» |
Тестов, зовущих обе функции, ноль; хеши не складываются; клауза противоречит инварианту 12 строками ниже (драфт берёт БАЗОВУЮ версию банка именно чтобы стоп его не двигал) | Сказано честно: test-only, каждый тест пинит по одному входу фолда; заодно поправлен близнец в snapshot_wave_test.go («byte-unchanged, TestGolden proves it» — голден его не видит) |
| A5 | «126 of the entries drive internal/pipeline» в Makefile и cmd/tmmutate/main.go |
Пак сам добавил записи: 134 из 221 |
счёт по каталогу: pipeline 134 при total 222; после правки grep -c '134 of' даёт 1 в каждом из двух носителей. ⚠ Дофикс сдвинул число ещё раз (каталог 225, pipeline 137) и оба носителя пере-сняты по каталогу: 137 of the 225 |
| A6 | Утверждение (4) пина расхождения: «каждая глава после пролога названа на одну ПОЗАДИ СВОЕГО ЗАГОЛОВКА» + текст падения «расхождение ЗАКРЫЛОСЬ, удали тест» | От заголовка глава не отстаёт вовсе (第一章 → «Глава 1»); отстаёт от ОРДИНАЛА. Хуже: под настоящим регрессом (титул из счётчика) утверждение предлагало удалить тест |
Пере-названо: это вопрос АДРЕСАЦИИ главы, а не расхождение 346; текст падения больше не предлагает удаление. Предъявлено: под будущим фиксом первым срабатывает утверждение (2) с верным сообщением |
| A7 | banknote.go: «а на локальную копию ничто не ссылалось» |
Ссылок было две, в той же функции | Комментарий описывает КОД, а не его починку: назван инвариант (CandidateTypes шире Types, неизвестный класс молча падает в term) |
| A8 | Шрамы автозамены «a the / the the / pass pass» — 9 в файлах пака (+1 в открытом ради A4) | grep -rhoE по internal cmd: было 18 в 9 файлах |
В файлах пака теперь 0 (счёт по четырём файлам), во всём движке осталось 8 — ⛔ их НЕ трогала: сплошной проход по корпусу владелец отложил в отдельный заход |
Класс B — механизм, а не проза.
| # | находка | что сделано | чем предъявлено |
|---|---|---|---|
| B1 ★ | Фикстуры на ЧИТАЮЩЕЙ стороне остались вырождены по НОМИНАЛУ: 第一节+第二节 ⇒ номинал == ординал. Мутация «манифест ре-деривирует заголовок из ординала» переживала ВСЮ батарею (19/19 ok); на боевой книге под ней уехал бы заголовок у 2084 из 2282 глав. Это моя же недоделанная диспозиция круга 3: класс закрыт в одной фикстуре из трёх |
Все три переведены на 第一节+第三节; ожидания привязаны к НОМИНАЛУ через явные headingFixtureNominals/zhFixtureNominals; заведена запись каталога |
manifest{chapter 2, chunk 0, unit 2, title "Глава 2"} vs cut{… title "Глава 3"} — мутация теперь красная. Фикстура печатает titles "Глава 1"/"Глава 3" при ординалах 1/2 |
| B2 | Гниль якорей ВСЕГО каталога вычислялась и молча выбрасывалась под -battery: отчётный цикл отсеивал не-выбранные записи ДО печати. 53 из 221 записи бьют в код радиуса перенарезки — после неё зелень опять означала бы «запись существует» |
Заведён статический линт живости по всему каталогу (файл читается, тестов не гоняет); гниль печатается и красит выход | Гниль сегодня 0 при 222 записях. КОНТРОЛЬ: подложенная запись с мёртвым якорем, которую -id НЕ выбирает, названа поимённо и уронила прогон |
| B3 | tar | tar выбрасывал статус источника — конвейер отдаёт статус последнего звена |
Две команды через && + промежуточный архив; --exclude=./bin |
ЧАСТИЧНЫЙ отказ источника: прежняя форма — «цепочка продолжилась ДА, exit=0, 2 файла из 2»; новая — «нет, exit=2». Копия 6.8 МБ вместо 17 |
| B4 | Политика few-shot жила списком из двух имён, тогда как гейт паритета находит армы глобом: третий арм один видит, другой нет | Армы находятся глобом и здесь; решение по few-shot ключевано МОДЕЛЬЮ РЕДАКТОРА, незнакомый редактор = отказ, а не дефолт | КОНТРОЛЬ: арм на gemini-3.1-pro-preview → whose few-shot decision is not recorded in editorKeepsFewShot |
| B5 | Дифф гейта печатал адрес указателя вместо значения (Stage.FewShot — *bool) — единственный адрес починки, который видит оператор |
Указатели разыменовываются в самом диффере (stdlib, least mechanism) | FewShot:&false против FewShot:<nil> вместо FewShot:0x1c79f07269e8 |
| B6 | У цели make mutations не было носителя: grep -c 'tmmutate' backend/README.md → 0 при 2 на make battery |
Четыре строки в backend/README.md, включая довод, почему цель НЕ входит в battery |
тот же прибор после правки: make mutations → 1, tmmutate → 1, контроль make battery → 2 |
| B7 | Ратифицированный критерий дизайн-пака физически неисполним: D39.224 п.8(2) требует рефлексивный тест по образцу TestEveryCutInputMovesTheTag, а тот рефлексирует по ИМЕНОВАННОМУ типу — тогда как payload снапшота и stageSnap были АНОНИМНЫМИ структурами внутри функции. По JSON так не сделать: 3 из 21 ключа omitempty и в payload дефолтной книги отсутствуют |
Оба подняты в именованные типы пакета — и только это: ни таблицы осей, ни гейта, ни одного нового ключа (шаг 1 принадлежит дизайн-паку, D39.224 п.7) |
TestGoldenDeterminism зелён против ЗАКОММИЧЕННОГО capture.golden, sha c1577859… не двигался, git status по testdata/ пуст. Чтение сильнее пере-снятия: пере-снятый голден мог бы согласиться сам с собой мимо репозитория |
Находка → что сделано → ЧЕМ ПРЕДЪЯВЛЕНО (все круги, ни одной открытой)
| # | находка | что сделано | чем предъявлено |
|---|---|---|---|
| 1 | линт словаря читал tpl.FewShot, не доходящий до провода классификатора |
линт сведён к System+User; второй отрицательный кейс в тесте |
возврат к прежней форме на копии → FAIL … a pack whose vocabulary lives only in ---FEWSHOT--- was reported to be missing only [] |
| 2 | гейт паритета армов сам был списком имён | армы ищутся filepath.Glob; пустая выдача — отказ |
подложенный pipeline-arm-newcomer.yaml → arms discovered: 3 → FAIL … mining.contrast_path is not set |
| 3 | гейт изымал ВЕСЬ стейдж редактора | изъятие сужено до модели и следствий модели | temperature: 0.4→1.9 в арме → FAIL … Stages differs |
| 4 | load замыкал внешний t, падение одного арма отменяло следующие |
t параметром |
сломанный glm → FAIL …/glm рядом с PASS …/mistral |
| 5 | экспорт-тест не покрывал --pairs (единственный режим по живому раскрою) |
оба режима одним хелпером | посадка в чанкере → export ЗЕЛЕНО, export --pairs: chapter 1 unit at chunk 3: heading = "Глава 1", want "" КРАСНО |
| 6 | док-комментарий TestExportGlossaryGateWithheld осиротел моей вставкой |
блок возвращён своей функции | sed -n по файлу: комментарий стоит перед своей func |
| 7 | номер в шапке == ординал главы во всех фикстурах | паритетный тест переведён на 第一章·第三章·第七章 |
посадка «рендерить из счётчика» → chapter 2 (header "第三章 继续") opens with heading "Глава 2", want "Глава 3" |
| 8 | пере-снятие армов двигает оба снапшота арм-прогона — не было названо | названо отдельным пунктом отчёта с механизмом, ценой и противовесом | четыре хеша замера ревьюера + два контроля; мои приборы (голден, сравнение c1/c2) смотрели мимо — это тоже записано |
| 9 | армы больше не конструируются без артефакта контраста и langpack | названо; пинг по STACK.md расширен на механическую половину |
две разные жёсткие ошибки NewRunner на копии |
| 10 | «proposed пуста вне стопа» держалось прозой |
два утверждения (run-start, авто-продолжение) + запись каталога |
посадка A → carries 3 proposal(s) after an AUTO-CONTINUE; посадка B → run-start read-out carries 1 proposal(s); премиса непуста (total=2) |
| 11 | origin означало провенанс и канал в одном документе |
поле переименовано в channel |
греп "origin" по bankexport.go — только terms[]; платформа поле не читает (её аллоулист без него) |
| 12 | висящая ссылка на снятый pipeline.bankTypeOK |
ссылка пере-написана на живой предмет | греп bankTypeOK по backend/ — 0 (контроль: CandidateTypes — 8 живых хитов) |
| 13 | «the three editor swap-arms» над списком из двух | число поправлено | греп по файлу |
| 14 | make mutations копировал .env и удалял вторым шагом |
копия делается tar --exclude=./.env; ⚠ якорь $(CURDIR) из круга 2 оказался неверным и заменён кругом 3 на каталог самого Makefile'а |
файлов в копии 432 при 433 в источнике, .env в копии 0 при 1; из КОРНЯ репо после правки круга 3 — тоже 0 |
| 15 | pipelineFieldDiffs паниковал бы на неэкспортируемом поле |
CanInterface() |
правка формы; сегодня таких полей 0 из 15 (контроль ревьюера) |
| 16 | в отчёте «8 pipeline + 1 chunk» вместо 8 и 2 | число пере-снято прибором | python3 по каталогу: battery=true 10 → pipeline 8, chunk 2 |
| 17 | пар-специфика в армах 0/0 → 2/2 | НЕ чиню (вне заказа), названо | счёт ревьюера по zh-ru/.zh. в configs/pipeline-*.yaml |
| 18 | словарь родов: текст ошибки не называл принимаемые короткие формы | перечень выводится из карты (knownGenderNames()) |
gender="m" ПРИНЯТ при старом тексте «is not one of male|female|neuter|hidden»; новый текст печатает f|female|hidden|m|male|n|neuter |
Пинги в чужие зоны (сама НЕ трогала)
-
docs/STACK.mdстрока 12 (зона оркестратора). Она говорит «резерв; флип = один арм-конфиг» и БУКВАЛЬНО верна, но теперь неполна в двух местах: (а) арм-файлов стало ДВА, а не три —pipeline-arm-deepseek-pro.yamlснят как совпавший с боевым; (б) цена подмены названа строкой 348 и она денежная — платформа берёт за банк плоские $2.00 по c1, и до этого пака арм ехал безmining.contrast_path, то есть пользователю выставили бы $2 за банк, которого никто не майнил. После пере-снятия армы контур несут, и денежная половина закрыта. ⚠ Но круг 2 нашёл ВТОРУЮ половину, которой в моём первом пинге не было, и она механическая: пере-снятый арм больше НЕ КОНСТРУИРУЕТСЯ безconfigs/mining-contrast.zh.txt(артефакт крупный, в git его нет по построению) и безlangpack_rootвbook.yaml—NewRunnerпадает громко на обоих. Это корректное следствие (арм стал настоящей копией боевого, а прежняя «работоспособность» держалась ровно на отсутствии банкового контура), но «флип = один арм-конфиг» теперь неверно и по этой причине тоже: флип требует развернуть артефакт контраста и дать книге langpack. Дописка нужна про ОБЕ половины. -
docs/BACKLOG.md, строка 346 (зона оркестратора) — фактическая поправка, а не косметика. Строка говорит: «84-рунный заголовок: ингестfalse, чанкерok=true(контроль на 12 рунах сходится)». Воспроизвела — и СНАЧАЛА НЕ ПОЛУЧИЛА: на строке第四章+ 81 руна оба предиката даютfalseпри ЛЮБОЙ длине. Причина не в длине: после юнита стоял контентный глиф, и оба предиката отвергают такую строку по РАЗНЫМ, но одинаково срабатывающим правилам. Расхождение воспроизводится только с СЕПАРАТОРОМ после юнита (第四章:…): 60 рун — обаtrue, 61 руна — ингестfalse, чанкерok=true, n=4. ⇒ строке нужна дописка «с сепаратором после юнита», иначе следующая смена повторит мою ошибку и заключит, что строка врёт. В тесте это уже зафиксировано контрольной парой 60/61 и предупреждением в комментарии. -
docs/BACKLOG.md, строка 350 (зона оркестратора) — вторая фактическая поправка: «„последняя стадия“ дважды одинаковым инлайном при готовомfinalStageWave()» называет не тот хелпер.finalStageWave()возвращает ВОЛНУ и уже имеет 10 прод-вызовов; дублировалось ИМЯ последней стадии, и хелпера для него не существовало. Я его завела (finalStageName()), но строку стоит поправить, чтобы «готовый хелпер» не читался как «работа уже сделана». -
docs/experiments/00-provider-quirks.md(зона полигона, читала только). Её строка про Gemini в цепочках эскалации перечисляет адреса «во ВСЕХ арм-конфигах:pipeline-c1.yaml:129,pipeline-arm-glm.yaml:61,pipeline-arm-deepseek-pro.yaml:62,pipeline-arm-mistral.yaml:61». Из четырёх адресов один теперь указывает на снятый файл, а два других сдвинулись пере-снятием армов. Сама не трогала — чужая зона; передаю тебе, чтобы дошло до полигона. ⚠ Само УТВЕРЖДЕНИЕ живо:gemini-3.1-pro-previewпо-прежнему в дефолтной цепочке обоих оставшихся армов и c1 (контроль: грепgemini-3.1-pro-previewпоbackend/configs/pipeline-*.yaml— 3 файла из 4: c1, arm-glm, arm-mistral; в c2 его нет). -
Платформенная половина строки 224. Движок теперь публикует предложенное отдельной секцией
proposedсайдкараtm-bank-v1; версия формата НЕ бампалась. Платформа читает по аллоулисту (platform/internal/ingest/bank.go,json.UnmarshalбезDisallowUnknownFields— проверено чтением, поле просто игнорируется), так что НИЧЕГО не ломается. Но экран подписи по-прежнему покажетtotal 0, signed 0, пока платформа не научится читать секцию: еёtotal/signedсчитаются по банковым терминам, а предложенные строки в банк не уезжают и уезжать не должны (иначе неподписанное инъектируется законом — D39.104 п.2). ⇒ вторая половина строки 224 — на платформе, и это её решение, не моё.
§10 — что НЕ удалось · что не проверено · где сомневаюсь
- Паритетный тест §4.4(A) не предъявлен мутацией, которую ловит ТОЛЬКО он. Каталожная запись
HEADING-…краснит его — но вместе с ним краснеют пять прежних тестов (TestChapterUnitJaWebnovel,TestSplitTextChapters,TestTitleRawIsTakenWhereTheCutAllowsIt,ingest_encoding_test.goи др.). То есть я показала, что тест ЖИВОЙ и говорит про свой предмет, но НЕ показала, что он ловит что-то, чего не ловит корпус. Его уникальный вклад — сквозной путьIngestEncoded→SplitChunksи то, что он остаётся зелёным под будущим фиксом (это предъявлено исполнением). Честная формулировка: не опровергнуто, но и не доказано, что он незаменим. Runner.snapshotID()— ноль прод-вызовов. Замерено и записано в комментарий, но НЕ решено: удалять его или нет — вне заказа этого пака (строка 350 его не называет). Оставляю как находку.- Влияние секции
proposedна РАЗМЕР сайдкара не мерено. На фикстуре три строки; на боевом стопе их было 82. Контексты и evidence я в секцию НЕ клала именно из-за размера (они остаются в текстовой стоп-таблице), но верхняя граница на реальной книге не замерена. - Форма секции
proposed— моё проектное решение, не ратифицированное. Поля выбраны под экран подписи (src · dst · kind · origin · freq · spread · conf · invented · contradicts · bank_holds · variants). Если платформе нужен другой набор — это правка одного проектора, но лучше решить ДО того, как она начнёт читать. - Не проверяла поведение
make mutationsна грязной копии при параллельной сессии. Цель снимаетcp -aрабочего дерева: если в момент копирования другая сессия правитbackend/, копия окажется полу-состоянием. Инструмент это заметит (он фингерпринтит цели и требует зелёный базлайн), но сообщение будет про базлайн, а не про гонку копирования. - Линт словаря классификатора ловит МЕНЬШЕ, чем звучит, и я это называю, а не подразумеваю. Он доказывает, что идентификаторы НА ПРОВОДЕ, но не что модели велено ими ОТВЕЧАТЬ. Пак, который глоссирует свои классы двуязычно («人名 (name)») и тут же велит отвечать по-японски, проходит зелёным — ревьюер построил такой пак и предъявил
PASS. Закрыть это по-настоящему может только отказ движка на off-vocabulary ответе вместо нынешнего «посчитать и выбросить» (terminologist.go,Log.WarnContext), а это смена поведения ПЛАТНОГО прогона, и она не в заказе этого пака. Ограничение записано в комментарии самого теста, чтобы следующая смена не приняла зелень за гарантию. - Пар-специфика в шиппинг-конфигах удвоилась и НЕ вылечена (находка 17 круга 2):
zh-ru/.zh.в армах было 0/0, стало 2/2. Это неизбежное следствие того, что арм обязан быть копией боевого, а перекос живёт в самом c1 и признан строкой 140. Чинить его внутри этого пака означало бы трогать c1 — вне заказа. Называю как долг, который пак УВЕЛИЧИЛ. - Снапшот арм-прогона сдвинут, и обнаружила это не я (находка 8 круга 2). Оба моих прибора смотрели мимо по построению: голден грузит собственный фикстурный конфиг, а сравнение загруженных значений я делала только по c1/c2. Урок конкретный: доказательство «ничего не сдвинулось» обязано перечислять, ЧТО именно прибор покрывает, — иначе оно доказывает про свой предмет, а читается как про весь пак.
- Решение по
batteryvs соседняя цель — размен, а не истина (см. довод числами выше). Это то место пака, где я больше всего готова услышать «сделай наоборот».
Цена самопроверки — числом, для владельца
| круг | форма | агентов | токенов | что нашёл |
|---|---|---|---|---|
| 1 | моя проверка исполнением по ходу постройки | 0 | — | форма фикстуры (4 абзаца = 2 юнита), граница 60/61 руны с сепаратором, несоответствие строки 350 настоящему хелперу, врущий текст ошибки словаря родов |
| 2–4 | веер Agent: тесты · боевой код · правки круга 2 · правки круга 3 |
4 | ≈0.70 млн | 22 дефекта, все в моей работе: два блокера (линт читал ---FEWSHOT---, гейт армов сам был списком), изъятие целой стадии, замыкание внешнего t, непокрытый --pairs, вырожденность по ординалу, сдвиг снапшота арм-прогона, окно с .env, ложный якорь $(CURDIR), ложное-зелёное ReasoningMaxTokens |
| 5 | воркфлоу по осям владельца: 7 линз × 3 скептика на находку + сводный вердикт | 146 | ≈13.8 млн | 38 находок выдержали опровержение, 8 сняты скептиками: весь класс А (8 ложных утверждений, включая перевёрнутый денежный довод и пере-набранную посылку, опровергнутую D39.137 15.08) и весь класс B (вырожденность по НОМИНАЛУ с ценой 2084 главы из 2282 · молча выбрасываемая гниль каталога · потеря статуса в конвейере tar · политика few-shot списком · адрес указателя вместо значения · цель без носителя · неисполнимый критерий дизайн-пака) |
| итого | 150 | ≈14.5 млн |
Что веер нашёл СВЕРХ того, что нашла я сама — честно. Мои собственные проверки хорошо ловили «работает ли гейт» и плохо — два других вопроса. Первый: правда ли то, что я написала словами. Восемь ложных утверждений класса А я не нашла ни одним своим кругом. ⚠ Поправка к моему же первому изложению: я сказала «три из них уехали в канон моими пингами» — это НЕВЕРНО, и я это пере-мерила. В канон моими пингами не уехало НИ ОДНО: git show <коммит>:docs/BACKLOG.md | grep -c 'за банк, которого никто не майнил' даёт 1 на 4d0b68e — коммите, который САМ И ЗАВЁЛ строку 348, до выдачи мне пака (контроль: та же единица на d3eb56b и bd652fd, то есть фраза стояла там всё время). Я её не внесла, а УНАСЛЕДОВАЛА и повторила в двух своих местах — в шапке собственного гейта и в пинге отчёта; оба исправлены. Цена ошибки поэтому другая, чем я сказала: не «я испортила канон», а «я трижды повторила чужую ложь, ни разу её не проверив», хотя опровержение стоит одного грепа. Второй: закрыла ли я то, что мешает. Вырожденность по номиналу (B1) — моя же недоделанная диспозиция круга 3: я объявила класс закрытым, закрыв его в одной фикстуре из трёх, и «ни одной открытой» в моей же таблице было неправдой. Неисполнимый критерий дизайн-пака (B7) я бы не увидела вовсе — он виден только тому, кто читает ноту и код одновременно.
⚠ В цену веера входит и авария: 146 агентов по моей инструкции сняли 123 копии дерева и забили /tmp до 98 %, отчего батарея дала [build failed] в десяти пакетах. Это моя ошибка оснастки, а не свойство метода: tar --exclude вместо cp -a даёт копию 6.8 МБ вместо 17, и уборка за собой стоит одной строки. Оба носителя формы уже исправлены — оркестратором в промтах и мной в шапке cmd/tmmutate/main.go.
⚠ Инцидент оснастки: мой же веер забил /tmp, и батарея посыпалась НЕ по коду
Воркфлоу-ревью подняло 146 агентов, каждый по моей инструкции снимал cp -a backend в скретчпад — 123 копии дерева, 4.3 ГБ. df -h /tmp → 5.7G из 5.9G (98 %). Батарея немедленно дала compile: writing output: no space left on device в modernc.org/libc ⇒ 10 пакетов [build failed] плюс два красных теста в пакетах, которых пак не касается. Ни одна из этих краснот не про код, и в результаты она не записана: числа ниже сняты после уборки. Класс известен — та же авария стояла предупреждением хоста в канале сессий от 03.09.
Убрала только СВОЁ: 123 каталога с копией backend/ в моём скретчпаде + 35 остаточных агентских каталогов + крупные бинарники проб; /tmp → 26 %. ⛔ Каталоги /tmp/go-build* НЕ трогала (их два, могут быть чужими) — ровно потому, что прецедент их сноса в канале уже описан.
Три собственные ошибки оснастки, которые я называю, потому что они мои:
- Один и тот же путь копии на всех агентов.
cp -a src destв СУЩЕСТВУЮЩИЙ каталог вкладывает, а не заменяет — у одного ревьюера настоящийbackend/.envоказался на уровень глубже, чем указывал его жеrm -f. Он это заметил и убрал; контроль сейчас:.envкрупнее 100 байт в скретчпаде — 0 (четыре подставных по 7–27 байт). - Ни одному агенту я не велела убирать копию за собой.
- Копия снималась
cp -aцеликом — 17 МБ вместо 6.8 МБ, которые даётtar --exclude=./.env --exclude=./bin(та самая форма, которую круг 4 заставил меня написать вMakefile). Свой же инструмент я применила к целиmake mutationsи не применила к собственной оснастке.
Чем предъявлено — команды и числа, снятые ПОСЛЕ последней правки
Батарея — ПОЛНЫМ списком пакетов, снята ПОСЛЕ последней правки (дофикс девятнадцати находок приёмки), на здоровом диске и при свободной памяти. make battery → exit 0, 3m14.3s; golangci-lint — 0 issues.
ok — 19, FAIL — 0, «no test files» — 4 (cmd/tmmutate, cmd/tmvet, internal/chunk/chunktest, internal/standdata). Это ровно входной базлайн оркестратора (19/0/4). Пакеты: cmd/tmctl 19.5s · archguard 27.6 · bookfile 1.1 · checks 12.6 · chunk 1.6 · config 1.8 · lang 1.1 · langscreen 1.0 · ledger 1.0 · llm 2.2 · membank 12.4 · miner 1.5 · obs 1.0 · pipeline 168.4 · runevents 1.0 · seed 1.0 · store 31.7 · terminology 1.1 · text 1.1. ⚠ Числа круга 8 (2m55.1s, pipeline 151.1) были сняты ДО дофикса и заменены здесь целиком; рост пакета — три новых утверждения дофикса плюс фоновая загрузка машины, состав ok/FAIL/«no test files» не двинулся. Мои пять новых/переписанных тестов пакета pipeline стоят 2.9 с под -race (замер -run по их именам), то есть в 152 с пакета они не видны.
Скипы ПОИМЁННО (4): TestMinerFullBookParity, TestCorpusBankKeyConflicts, TestHelperEventsRun, TestHelperKillLoop — все четыре стендовые/хелперные, те же, что до пака.
⚠ После этого замера дерево ещё раз тронуто — двумя КОММЕНТАРИЯМИ (Makefile и cmd/tmmutate/main.go: число 135 of 222 пере-снято по каталогу в 137 of the 225 и сведено в одну строку, чтобы перенос не прятал его от грепа). Батарея пере-прогнана ПОСЛЕ них и подтверждает: make battery → exit 0, 3m29.4s, 0 issues, 19 ok / 0 FAIL / 4 «no test files», те же 4 скипа. Разница во времени (3m14 → 3m29, pipeline 168 → 182 с) — фоновая загрузка машины, а не правки: состав ни одной строкой не двинулся.
Мутационный гейт. make mutations → exit 0, 3m59.7s, «14 mutation(s) run, 0 unexpected outcome(s)», 14 RED, выживших нет; строка anchors swept: 0 of 225 entr(ies) rotten печатается ВСЕГДА, то есть гниль якорей 0 при 225 записях и ноль идёт со знаменателем (и линт теперь считает якоря тем же прибором, что посадка — круг 6); осиротевших каталогов /tmp/tmp.* после прогона — 0.
Отказы гейта — предъявлены ИСПОЛНЕНИЕМ, а не описанием (на копии дерева):
- пустое подмножество (снял
batteryсо всех записей подмножества — на момент этой пробы их было 9, после дофикса 14):tmmutate: the catalogue marks no entrybattery… a gate with no members proves nothing, exit 1; battery+expect:"survives":tmmutate: A-lock-arbiter: an entry with expect "survives" cannot be in the battery subset…, exit 1;-batteryвместе с-id:tmmutate: -battery and -id are two selections; pass one, exit 2.
Уборка и чистота дерева после мутационного прогона. Каталогов /tmp/tmp.* после make mutations — 0. В рабочем дереве изменённых файлов backend/ — 32, и среди четырёх файлов, куда сажались мутации, диффом отличается ТОЛЬКО export.go — моей же правкой свёртки инлайна (1 вставка / 4 удаления); manifest.go, chunker.go, bookrun.go — 0 строк. Посадок в дереве не осталось.
Снапшот-нейтральность — два независимых замера.
- Голден.
capture.goldenпере-снятTM_UPDATE_GOLDEN=1на дереве HEADbd652fdи на моём: sha256c1577859f434654698b344975529093cc5f6bd732d107a9fff523e0664e34971у обоих и у закоммиченного файла,diff— 0 строк при 252 строках файла. КОНТРОЛЬ: на третьей копии заведомо сдвинутchunkerVersion→ 196 строк расхождения и другойsnapshot_draft(37e97bf1…против3db58425…). То есть ноль — настоящий. - Шиппинг-конфиги. Правки комментариев в
pipeline-c1.yaml/pipeline-c2.yamlголден НЕ покрывает (он грузит собственныйtestdata/golden/pipeline.yaml). Замерено отдельно: HEAD-копия каждого файла и рабочая грузятсяLoadPipelineи сравниваютсяreflect.DeepEqual— равны обе пары (c1: 2 стадии,gates.terminology.enabled=true; c2: 3 стадии). КОНТРОЛЬ: тот же прибор на c1 против c2 расхождение ВИДИТ (core «C1» vs «C2», стадий 2 vs 3). Механизм, почему иначе быть не могло: в снапшот фолдятся РАЗОБРАННЫЕ значения плюс канонический (со снятыми комментариями) SHA промта — байтов YAML-файла не хеширует ничто (brief_hashсчитается по полямbook.yaml,config/book.go:391).
Дифф ^func Test — исполнением. HEAD bd652fd: 1257; дерево: 1265 (+8). Файлов _test.go: 204 → 207. Восемь новых: TestIngestAndChunkerAgreeOnOrdinaryChapterHeaders, TestIngestAndChunkerDivergeOnAZeroPrologueAndALongHeader, TestAnArmIsTheProductionConfigWithADifferentEditor, TestEveryClassifierPromptSpeaksTheEnginesVocabulary, TestTheRunStartReadOutAlreadyCarriesTheSeededBank, TestExportCarriesTheChapterTitleOnTheUnitThatOpensTheChapter, TestBankStopPublishesItsProposalsInTheReadOut, TestTheBuiltBookCarriesChapterTitlesAndNotTheirNumbers (последний — дофикс, закрывает симптом, с которого пак начинался). Прибор — comm -13 над отсортированными списками имён из HEAD и из дерева, а не разность двух счётчиков.
Каталог мутаций. 211 → 225 записей (+14, чистая дописка: git diff --numstat даёт 182 0, ни одной удалённой строки — сериализация каталога воспроизводится json.dumps(indent=1) побайтово, это проверено сравнением с оригиналом ДО правки). battery=true — 14 (11 в ./internal/pipeline/, 2 в ./internal/chunk/, 1 в ./internal/config/ — до дофикса верификатора там было 0), из них expect=survives — 0.
Армы. Не-комментарных строк расхождения с pipeline-c1.yaml: было glm 24 / mistral 24, стало 3 и 3 (ровно model: и снятая строка few_shot: false). КОНТРОЛЬ: c1 против себя — 0.
Деньги
Пак $0. Платных вызовов — ноль. Ни одной генерации, ни одного обращения к провайдеру: все прогоны — go test с фейковым httptest-провайдером и детерминированные проекции. Ключи не читались, .env не открывался ни разу (и удалялся из каждой снятой копии дерева — find по скретчпаду даёт 0 файлов .env при живом backend/.env в рабочем дереве).
КРУГ 6 — по правкам КРУГА 5: 15 находок, круги НЕ сошлись с первого раза
Воркфлоу из 48 агентов, три линзы (исправленные утверждения · механизмы · подъём боевых типов), по два скептика на находку. Ни одна не ставит под сомнение лендинг — боевой код, деньги и сам фолд снапшота чисты, подъём проверен независимо и жёстче голдена (третье дерево с механически откаченным подъёмом дало побайтово тот же дамп 72 payload'ов, sha256 совпал, AST-сверка набора и порядка полей — идентична). Но дефекты в МОИХ ЖЕ правках круга 5 нашлись, и главный — снова повторение собственного класса.
| # | находка | что сделано | чем предъявлено |
|---|---|---|---|
| ⛔ A2 | Индексация номинала БЕЗ ГРАНИЦЫ в трёх фикстурах — ровно тот класс, для которого я двумя кругами раньше поставила границу в headingparity_test.go и написала в комментарии, что паника вместо сообщения недопустима. Третья глава ⇒ panic: index out of range, и вердикт по 135 из 222 записей каталога умирает разом. Третий носитель был прикрыт СЛУЧАЙНО — более ранняя проверка срабатывала первой |
Хелпер zhNominal(t, chapter) с t.Fatalf в pipeline, явная граница в chunk |
Укороченная до одной главы таблица: the cut produced chapter 2 and the fixture declares 1 headers в ОБОИХ носителях pipeline — сообщение, не паника |
| ⛔ A1 | Мой новый линт считал якоря НЕ ТЕМ ПРИБОРОМ, что посадка: catalogueRot — по чистому телу файла, one() — по накопительному patched. Запись, чей второй якорь уникален только после первого edit'а, отработала бы RED и всё равно уронила прогон как «гниль». Заряжено на 7 записях из 222 (поимённо: B-report-mitigations, FC1-cell-key, FC7-…, WB36-…, WB43-…, WB60-…, WB64-…) |
Линт считает по накопительному тексту и per-file, как посадка | WB60-volume-report-decided-after-reconcile → RED, секции CATALOGUE ROT нет |
| ⛔ A3 | Рецепт копии в шапке инструмента буквально НЕ ИСПОЛНЯЛСЯ: tar … -C backend . требует cwd = корень репо, go run ./cmd/tmmutate — cwd = backend/, cd между ними не было. Он же раздавал конвейер tar | tar, который Makefile в этом же дереве называет причиной ложного дефекта |
Рецепт приведён к форме цели mutations: две команды через &&, cwd назван явно |
Исполнен буквально: 430 файлов, .env 0, 6.8 МБ, go build ./... в копии проходит |
| B4 | «134 of 221» неверно в ОБОИХ числах | 135 of 222 в обоих носителях |
счёт по каталогу. ⚠ Дофикс сдвинул каталог ещё раз — сегодня в обоих носителях 137 of the 225, и число сведено в ОДНУ строку в каждом, потому что перенос строки в Makefile прятал его от грепа, которым его же и проверяют |
| B5 | «полный прогон — шесть часов» опровергнут собственным замером: инструмент гоняет БЕЗ -race (grep -c '\-race' cmd/tmmutate/main.go → 0 при контроле 4 в Makefile), значит ~16 с на запись, ≈40 мин, а 6 ч — это та же арифметика по цене батареи с -race |
Число пере-обосновано честно: назван и режим, и то, что 40 минут всё равно не гоняют по правке | грепом по обоим файлам |
| B6 | Шапка snapshot_wave_test.go врала о СВОЁМ ЖЕ файле: «эти тесты тоже зовут snapshotID()» — в файле ноль таких вызовов |
Сказано, где живут его четыре вызывающих | грепом |
| B7 | Шапка stageSnap занижала собственный довод вчетверо: «three of its slots are omitempty» — у stageSnap 12 из 19, число 3 принадлежит snapshotPayload (21 ключ) |
Оба числа названы своими типами | счёт по телам типов |
| B8 | TestSwapArmConfigs перестал пинить, какой редактор в каком арм-ФАЙЛЕ — глоб плюс ключевание моделью оставили имя файла, единственную ручку выбора арма под деплой, без сторожа |
Слаг выводится из pipeline-arm-<slug>.yaml и обязан входить в модель редактора — из ИМЕНИ, а не списком |
КОНТРОЛЬ: подмена редактора mistral-арма на glm-5 (раньше проходила) → resolves editor "glm-5", which does not carry the file's own slug "mistral" |
| C | Пять мелочей: «по одному входу каждый» при вызывающем, пинящем два · README не называл гниль каталога вторым поводом ненулевого выхода · маска ./.env против ./.env* в двух носителях одного правила · у подъёма нет потребителя и носитель обязательства не назван в коде |
Все пять дописаны/выровнены | грепом по обоим носителям маски |
B9 — пинг оркестратору, не моя зона. Ратифицированный якорь D39.224 п.8(1) адресует ключи снапшота ДИАПАЗОНОМ СТРОК (snapshot.go:342-425). Диапазон протух: счёт по нему даёт 21 и в HEAD, и в дереве, но НАБОР другой — в него попали 6 ключей stageSnap и выпали 6 ключей payload. ⚠ И честная оговорка: нота говорит «22 ключа, счёт мой», то есть её счёт не сходился с HEAD (21) ещё ДО моего подъёма — сверка по числу не поймает, она даст третье число. Настоящие адреса после подъёма: snapshotPayload — 21 ключ, stageSnap — 19. Рекомендация: адресовать ИМЕНЕМ типа, а не диапазоном строк, — теперь это возможно.
КРУГ 7 — по правкам КРУГА 6: лендинг ДА, блокеров 0; две находки уровня «механизм врёт», обе — в инструменте, не в движке
Воркфлоу из 29 агентов, две линзы (починки круга 6 · что мешает лендингу), по два скептика на находку. Ни одна находка не лежит в боевом Go. Круг 2 внёс ложный якорь, круг 3 — ложное-зелёное, круг 5 — паникующую индексацию; круг 6 регресса в движок не внёс ни одного. Плотность дефектов уехала из движка в отчётность инструмента о себе — это признак близкой сходимости, а не сходимость.
| # | находка | что сделано | чем предъявлено |
|---|---|---|---|
| ⛔ 1 | Мой новый подметатель гнили ВРАЛ ЧИСЛОМ. Сентинел bodies[path] = "" служил и «нечитаем», и «пустой файл», а if body == "" { continue } глотал все последующие записи по тому же пути. На пустом корне шапка печатала «47 of 222», тогда как мертвы были все 222 — 175 сгнивших записей читались как живые. Обратный перекос там же: одна запись с двумя мёртвыми якорями давала «2 of 1 entr(ies)» |
Отдельный unreadable map[string]bool вместо перегруженной пустой строки; шапка считает по УНИКАЛЬНЫМ записям, а не по сообщениям |
вызов настоящей функции в изолированном тесте: пустой корень → «сообщений 231, записей 222, шапка напечатает 222 of 222»; живое дерево → «сообщений 0, записей 0» при контроле «записей в каталоге 222» |
| ⛔ 2 | Рецепт копии в шапке инструмента утекал .env, и лечили ровно этот якорь этажом ниже. Makefile получил -C "$(MAKEFILE_DIR)" с замеренным доводом, а шапка осталась с голым tar … . под комментарием «# from backend/». Замер на фикстуре: теми же флагами на каталог выше — .env members = 2 при контроле total members = 9, в архиве ./backend/.env и ./backend/.env.example |
В рецепт добавлен ИСПОЛНЯЕМЫЙ страж [ -f go.mod ] || { echo "run this from backend/"; exit 1; } и сказано, почему он не декорация |
из backend/: 430 файлов, .env 0; из корня репо страж срабатывает (go.mod там нет) |
| 3 | Новый фикстурный хелпер zhBookWithChapterHeadings делал strings.Replace("source_lang: ja", …) БЕЗ стража — молча вернул бы вход и скормил бы двум тестам ja→ru книгу без langpack, где все сравнения заголовков снова "" == "". Дом уже носит защищённую форму того же в двух других файлах |
Добавлена проверка предпосылки с текстом «premise broken» | форма приведена к существующей в classifyinput_test.go и contourpreflight_test.go |
| 4 | Довод «counting each against the pristine body would report seven entries as rot» не воспроизводится: обе схемы на живом каталоге дают 0. Семь — это счёт записей В ЗОНЕ РИСКА, поданный как измеренное следствие | Довод переписан на то, что правда: сегодня схема не нужна ни одной записи, семь — риск, а не промах | замер обеих схем |
| 5 | snapshot.go: «12 из 19 слотов omitempty и отсутствуют в payload дефолтной книги» — арифметика верна, «отсутствуют» нет: на голдене стадия draft несёт 3 из этих 12 |
Сказано, что именно зависит от книги, и названы 3 из 12 на голдене | счёт по голдену |
| 6 | Шапка golden_test.go пиннула «the snapshotID + payload», хотя файл зовёт только snapshotIDForWave — третий носитель той же поправки |
Названы волновые фолды и то, что книжно-глобальный здесь НЕ пиннут | грепом: .snapshotID() — 5 вызовов, все в других _test.go |
| 7 | README.md: «ДВА повода для ненулевого выхода» не исчерпывающе — их семь |
Перечислены все | по адресам main.go |
| ⛔ 8 | «Единственная заказанная смена поведения — §4.2(а)» верно для c1/c2 и НЕВЕРНО для армов. Пере-снятие дало обоим армам банковый контур: прогон по арму теперь ПОКУПАЕТ то, чего не покупал |
Вторая смена поведения названа отдельным блоком в исходе по §4 — с ключами, с диффом и с ценой | git diff --numstat: glm 37/29, mistral 43/31; ключей контура в каждом — 5 |
Что круг 7 проверил и НЕ нашёл: ни одного дефекта в боевом Go; границы круга 6 дают сообщение, а не панику; армовый гейт краснеет на трёх мутациях; мутационная батарея дважды «11 mutation(s) run, 0 unexpected»; голден зелён против закоммиченного файла; загруженные c1/c2 HEAD↔дерево равны; на снятый арм-файл не ссылается ничто исполняемое; чужих зон в диффе нет.
КРУГ 8 — по восьми починкам КРУГА 7: КРУГИ СОШЛИСЬ на уровне механизма
Воркфлоу из 18 агентов, одна линза, по два скептика на находку. Вердикт: находок уровня «механизм врёт или ломается» в движке и гейтах проход НЕ дал; блокеров 0; лендингу не мешает ничего. Осталось восемь правок уровня строки — все закрыты, ниже с предъявлением.
| # | находка | что сделано | чем предъявлено |
|---|---|---|---|
| 1 | Мой страж рецепта ЗАКРЫВАЛ интерактивный терминал оператора: [ -f go.mod ] || { …; return 1 2>/dev/null || exit 1; } — замер на pty из каталога без go.mod: «child still alive after the guard line: False» и в bash 5.3.9, и в dash; контроль с заменой стража на : — True у обоих |
Страж стал звеном цепочки: [ -f go.mod ] && d=$(mktemp -d) && …, без exit вовсе |
шелл жив после стража; из backend/ рецепт даёт 430 файлов и .env 0 |
| 2 | Шапка ROT восстанавливала id разбором собственного текста (префикс до первого :). При id с двоеточием счёт врал: замер — «dead entries 4, rot messages 4, header would print 2 of 4» |
catalogueRot возвращает пару (сообщения, число ЗАПИСЕЙ), id собираются по ходу |
пустой корень → «сообщений 231, записей 222» при контроле «в каталоге 222»; запись с id X:probe и двумя мёртвыми якорями → «сообщений 2, записей 1» |
| 3 | Класс незащищённого strings.Replace("source_lang: ja", …) я закрыла в 1 площадке из 6 — уехавший якорь молча даёт ja→ru книгу без лангпака, где сравнения заголовков снова "" == "" |
Страж «premise broken» добавлен в три оставшиеся | 6 из 6 площадок несут страж (счёт по файлам идиомы) |
| 4 | Пример в шапке -id A-lock,G-byte-gate при копипасте падал: no mutation "A-lock" in the catalogue |
A-lock-arbiter |
обе записи есть в каталоге |
| 5 | «A full run is six» — без единицы, и цифра чужая: Makefile того же пака её уже поправил |
«~40 min без -race — режим, в котором гоняет этот инструмент» |
оба носителя согласованы |
| 6 | README.md: перечень поводов ненулевого выхода объявлен исчерпывающим и не полон (не названы переименованный run-фильтр, невалидный каталог, пустое подмножество, неизвестный -id) |
Перечень дополнен, и вместо обещания исчерпывающести дан АДРЕС полного перечня — ветки в исходнике | по адресам main.go |
| 7 | Три доккомментария слиплись в один над zhNominal, а zhBookWithChapterHeadings и mustIngestChapters остались без описания |
Каждый вернулся своей функции | у каждой из трёх свой комментарий |
| 8 | В моём же отчёте «glm +66, mistral +74» прочитано как ВСТАВКИ, а это сумма столбца --stat |
По --numstat: glm 37/29, mistral 43/31 |
тем же прибором |
⚠ Поправка к предъявлению круга 7, найденная кругом 8 и принятая: доказательство «на пустом корне гейт печатает 222 of 222» через go run … -root <пустой> НЕ воспроизводится — прогон останавливается раньше на «./internal/pipeline/ is NOT GREEN before any mutation is planted». Суть находки верна и доказана прямым вызовом catalogueRot в изолированном тесте (так в отчёте и записано), но САМ СПОСОБ замера, будь он взят из вердикта круга 7 дословно, не сработал бы. Разница между «утверждение верно» и «этой командой оно проверяется» — ровно то, что этот пак и ловит.
ДОФИКС ПРИЁМКИ — два верификатора оркестратора, 19 находок, ни одной блокирующей
Оркестратор честно пометил, что это ЕГО замеры, а не мои, и велел пере-снимать самой. Пере-сняла каждую. Все подтвердились, кроме одной (A), которая оказалась уже покрытой моим же дофиксом — и это я тоже сказала числом, а не «наверное».
Верификатор 1 (судил дифф против заказа, отчёт не читал):
| # | находка | пере-снято мной | что сделано |
|---|---|---|---|
| F1 | Линт словаря пинит ОДНО направление и сжимается вместе со своим предметом: удаление слова из terminology.Types снимает и утверждение о нём |
выкинула "title" из Types → 19 ok / 0 FAIL, не ловит ничто |
Страж на вырожденный предел (len(classifierVocabulary()) == 0), брат к уже стоявшему «нет classifier.md вовсе». ⚠ Границу называю сама: общий случай «слово убрали» линт по построению не ловит; настоящий дом — пин самого словаря, которого в репозитории нет (ресёрч: 0 тестов на terminology.Types). Заказу это не принадлежало |
| F2 | {{title}} удовлетворял слово класса title — плейсхолдер подставляется ДО модели |
локализовала оба настоящих вхождения, оставив плейсхолдер → тест ПРОШЁЛ и числил title утверждённым |
Плейсхолдеры {{…}} снимаются перед поиском: их ИМЕНА — не текст, которым инструктируют модель. Контроль: та же локализация → never names [title] where the model can see it |
| F3 | Строки листа подписи могут потерять ВСЕ решающие поля и остаться зелёными | свела проекцию к {Src,Dst,Freq} → пакет ok |
Сверка проекции со СТРОКОЙ СТОПА поле в поле (Kind↔Type, Channel↔Origin, Spread, Conf, Invented, и раздельно Contradicts/BankHolds, как настаивают комментарии самого типа) |
| F7 | «фикс приземлился, сложи тест в паритетный» висело на страже ПРЕДПОСЫЛКИ | адрес прочитан | Страж говорит своё: «изменился предикат заголовка САМОГО ингеста, а расхождение ниже не судилось ни в какую сторону» |
| F4 | Гейт армов обнуляет ReasoningMaxTokens, значит арм с абсурдным значением остаётся зелёным |
отклонила доводом с числом | providerReasoning кодом, а не грепом: additive — 1 модель (grok-4.3) при контроле subset — 7; оба живых арма subset, rmt=0. У боевого этого ключа НЕТ и быть не может ⇒ сравнивать не с чем, любая проверка была бы ПОЛИТИКОЙ, придуманной тестом. Правильный дом — смета трат или загрузчик. Вместо неё изъятия названы в логе прогона, чтобы зелень не читалась как «сравнено» |
| последний хоп | Симптом, которым пак ОТКРЫВАЕТСЯ — книга с «1» и «2» вместо названий — рождается в bookbuild.go и не назван ни одним из 90 тест-файлов пакета |
подтверждено | Закрыт, и это ДВЕ гарантии, а не одна: заголовок становится названием главы, и он же снимается с тела, чтобы не задвоиться. Новый тест в bookbuild_test.go, обе занесены в каталог. Предъявлено: потеря заголовка → the built book has no chapter titled "Глава 1" — assembleBook substitutes the chapter NUMBER…; неснятый префикс → "Глава 1" appears 2 times in the built book, want 1 |
⚠ Поправка к моему же контролю: первый прогон контроля по неснятому префиксу дал ЧУЖОЙ текст — я держала обе посадки в одной копии. Пере-снято на чистой: дамп книги под одной посадкой — "Тест\n\n\nГлава 1\n\nГлава 1\n\nОТРЕДАКТИРОВАННЫЙ…", ровно задвоение.
Верификатор 2 (смотрел вне карты отчёта):
| # | находка | пере-снято мной | что сделано |
|---|---|---|---|
| A | Своп Kind↔Channel и Freq↔Spread в проекции проходит зелёным; человеческая таблица стопа печатает те же величины, значит JSON и таблица ОДНОГО стопа разошлись бы четырьмя колонками молча |
посадила своп → FAIL, the projection lost deciding fields |
Уже покрыто дофиксом F3. Отвечено числом, ничего не добавляла |
| B | Замер утечки ключей в Makefile занижен вдвое и умалчивает чужую зону |
пере-мерила: сломанная форма — 61023 члена архива, 2 .env (backend/.env И eval/.env — ключи полигона); починенная — 488 и 0 |
Числа в комментарии заменены на настоящие, пересечение зоны названо |
| C | Зелёный гейт не печатал контрольную величину свипа гнили — оператор не отличал чистый свип от несостоявшегося | воспроизведено чтением кода: баннер только при len(rot) > 0 |
Печатается ВСЕГДА: anchors swept: 0 of 225 entr(ies) rotten. Это ⛔-норма проекта, которую я цитирую в отчёте и нарушила в своём же инструменте |
| D | Сгнившая запись считалась дважды: и прогонным циклом, и статическим свипом, а списки склеивались | посадила запись с мёртвым якорем и ВЫБРАЛА её | Два раздельных числа вместо склейки: 1 unexpected outcome(s) [ZZ-DOUBLE-PROBE (rotted)]; 1 rotted entr(ies) |
| E | Два моих носителя называли цену гейта в ПРОТИВОПОЛОЖНЫХ направлениях (README «87 %», отчёт «104 %»); контрольные числа подмножества неверны; отчёт трижды учил форме cp -a, которую мой же Makefile называет опасной |
сверено грепом по обоим файлам | Цена названа диапазоном 87–104 % по девяти прогонам в обоих носителях — брать край разброса как довод нельзя. Числа подмножества пере-сняты. Утверждения про cp -a разведены: где историческое — сказано, что форма сменилась; где описывало ДЕЙСТВУЮЩУЮ цель — исправлено |
| F | Арм mistral вёз доллары из АРХИВНОГО плана на опровергнутом ценовом базисе, а его сосед в этом же диффе получил ⚠ про пере-пин цен | сверено с шапкой архива и с models.yaml |
Числа СНЯТЫ, а не пере-процитированы: названы источник, его статус «история дизайна, не действующий план», и что базис опровергнут D39.137 |
| G | Строка лога клала рядом вложенное и непересекающееся число — читается как доля от банка | прочитано | proposed → awaiting_signature_outside_the_bank, с оговоркой у кода, что approved ⊂ terms, а эта величина с ними не пересекается |
| H | У гейта равенства армов не было записи в каталоге: 0 из 14 в ./internal/config/ |
подтверждено счётом по каталогу | Запись заведена. ⚠ Первая посадка краснела НЕ ТЕМ механизмом — её ловил загрузчик, а не сравнение; это «правый вердикт по неправой причине», и я пере-посадила на ключ, который загрузчику безразличен (cache_ttl). Текст падения теперь: is not pipeline-c1.yaml with a different editor — Context differs |
Ссылка на ноту — нашёл он, чиню я. В теле D38.4 слово few_shot встречается 0 раз; носитель — D38.5, и тема стоит в самом его заголовке (3 хита в теле). Пере-проверила своим прибором по архивному слайсу. Исправлено в семи строках, которые написал или перенёс этот пак (pipeline-c1.yaml, pipeline-arm-glm.yaml, echo_mine_test.go ×4, snapshot.go). ⚠ Остаток: ещё 6 строк с той же неверной ссылкой в чужих, не тронутых паком местах (fewshot_test.go ×3, render.go, runner.go, config/pipeline.go) — не трогала, сплошной проход по корпусу владелец отложил; называю числом.
Знаменатель по каждому классу: «закрыт в N носителях из M», а не «закрыт»
Столбец заказан оркестратором для приёмки, и повод конкретный: на классе «вырожденность по номиналу» я объявила «ни одной открытой», закрыв его в ОДНОЙ фикстуре из трёх. Ниже — каждый класс с явным знаменателем и с тем, чем знаменатель посчитан.
| класс | закрыт | чем посчитан знаменатель | чем предъявлено закрытие |
|---|---|---|---|
| Вырожденность фикстуры по ЧАНКАМ/ЮНИТАМ (глава даёт ≥2 чанка И ≥2 edit-юнита) | 3 из 3 | все фикстуры шва: chunker_heading_test.go, contractblockers_test.go, export_test.go |
числа печатаются и УТВЕРЖДАЮТСЯ в каждой; cut: 8 chunks; chunks per chapter map[1:4 2:4]; edit units per chapter map[1:2 2:2] |
| Вырожденность фикстуры по НОМИНАЛУ (номер в заголовке ≠ ординал главы) | 3 из 3 (было 1 из 3 при моём же «ни одной открытой») | те же три носителя | мутация TITLE-the-number-in-a-title-is-the-headers-not-the-ordinals → manifest{… title "Глава 2"} vs cut{… title "Глава 3"}; фикстуры печатают titles "Глава 1"/"Глава 3" при ординалах 1/2 |
Утверждение «не-первый чанк несёт пустой Heading» |
3 из 3 сторон шва: разрез · реконструкция манифеста · экспорт (и на экспорте — 2 из 2 режимов, export и --pairs) |
export.go развилка pairs → bookChunks() против readModelChunks() |
четыре мутанта M1/M2/M3/M5 красные; мутация только чанкера краснит именно --pairs |
| Списки, перечисляющие армы поимённо | 2 из 7 (гейт паритета и TestSwapArmConfigs — глобом; политика few-shot — по МОДЕЛИ редактора) |
grep -rn 'pipeline-arm-' internal/ --include='*_test.go': 7 площадок |
подложенный третий арм: гейт паритета его находит и роняет, TestSwapArmConfigs требует записанного решения по few-shot. ⚠ Остальные 5 списков НЕ переведены (content_labels_test.go ×2, echoregen_shipping_test.go, prompt_pack_test.go, promptlabel_test.go) — вне заказа, назван долг |
| Ложные утверждения в комментариях пака | 8 из 8 найденных | линза «комментарии» + линза «история», по диффу пака | каждое опровергнуто командой, перечислены в круге 5 |
| Шрамы автозамены «a the / the the / pass pass» | 10 из 18 — те, что в файлах, которые пак и так открыл | grep -rnoE по internal cmd: 18 в 9 файлах |
⛔ Остальные 8 НЕ трогала намеренно: сплошной проход по корпусу владелец отложил в отдельный заход |
| Гниль якорей каталога | 225 из 225 проверяются статически при каждом прогоне гейта | линт catalogueRot обходит весь каталог, не выборку |
гниль сегодня 0; КОНТРОЛЬ — подложенная запись с мёртвым якорем, которую -id НЕ выбирает, названа и уронила прогон |
Незащищённый strings.Replace("source_lang: ja", …) в фикстурах (уехавший якорь молча даёт книгу без лангпака) |
6 из 6 (было 1 из 6 после круга 7, нашёл круг 8) | grep -c по площадкам идиомы в internal/pipeline/*_test.go |
у каждой площадки страж «premise broken»; форма взята у двух, где она уже стояла до пака |
| Функции без вызовов (строка 350) | 6 из 6 решены («оставить, причина названа на месте») | квалифицированный греп по каждой; контроль chunk.SplitChunks = 12 живых вызовов |
у каждой в определении назван факт «вызова нет» и кто её держит |
⛔ ЧЕСТНЫЙ ИТОГ ПО ЗАДУМКЕ, а не по чеклисту (заказ владельца 07.09)
Мерило владельца — «техдолг, который мешает СЕЙЧАС и требует рефакторинга ПРЯМО СЕЙЧАС, не по заказу, а по необходимости и с учётом планов». Мерить надо по §2.А ресёрча — четыре вещи, тормозящие разработку СЕГОДНЯ. Вот честный счёт:
| §2.А | предмет | закрыт паком |
|---|---|---|
| 1 | Норма «копить wire-правки одним касанием». Корень механический: classifySnapshotMove знает ОДНО re-pinnable поле (repin.go:54 const memoryVersionField) при 21 ключе payload; всё остальное = moveOther = не пере-пиньится ничего |
НЕ ТРОНУТ. git status --short backend не содержит ни repin.go, ни rebill.go |
| 2 | Лендинг данных заблокирован порядком (embedded_version — один хеш на 8 файлов с тремя радиусами взрыва) |
НЕ ТРОНУТ. internal/lang/** в диффе отсутствует |
| 3 | Порядок предвычисления не пиненный | Закрыт наполовину: каталог 211→225, гейт построен и вызывается, но сам порядок в mining.go не двинут (лечение аддитивное), а гейт стоит СНАРУЖИ battery — объявленный размен |
| 4 | Шов заголовка не утверждается ничем | ЗАКРЫТ. Плюс сверх заказа закрыт класс, которого в заказе не было: номинал главы против её ординала |
Это не вина заказа и не оправдание: D39.224 и §5 ресёрча отдали Д5 дизайн-паку, а Д4 — окну перенарезки, и закрывать их шагом 0 канон прямо ЗАПРЕЩАЕТ. Но и ответ на вопрос владельца звучит прямо: пак закрыл шаг 0 добросовестно и оставил корень.
Корень одним предложением. У главы сегодня ТРИ разных числа-адреса — плотный ординал (PK chunk_status, адрес redrive), номинал заголовка и контентный chapterID манифеста, — и пока предикат осей знает одно re-pinnable поле, любая правка кроя, грамматики заголовка или langpack-данных перекупает книгу целиком; отсюда и норма «копить», и запрет лендинга данных, и невозможность починить 第0章 дешевле глобальной перенарезки.
Что из НЕ взятого я проверила на «а не стоило ли сейчас» — и с каким исходом:
| кандидат | вердикт | довод |
|---|---|---|
Д2 ThinksOnWire → делегация |
НЕ сейчас | §6 ресёрча прямо запрещает тащить снапшот-нейтральные мелочи в окно перекроя, а носитель (строка 114в) велит брать «при следующем касании файла». Пак capability.go/models.go не касался — 0 из 31 изменённого пути. Возьмёт тот, кто их откроет |
| Д5 предикат осей | НЕ сейчас | ратифицированный критерий дизайн-пака; второй исполнитель — ровно то, от чего предостерегает D39.224 п.7. НО его критерий был физически неисполним, и эту блокировку я сняла — см. B7 |
Д4 EmbeddedVersion |
НЕ сейчас | сам ремонт бампает хеш и CUT-тег: отдельным актом платит ту цену, которую отменяет |
Д8 три семантики ординала, Chapter.ID |
НЕ сейчас | шаги 2 и 3 — ОДНА перенарезка, разнести = заплатить дважды |
Фикс 第0章 (346б) |
НЕ сейчас | меняет ТЕКСТ чанка ⇒ chunkerVersion ⇒ обе волны. Замер: classifySnapshotMove на сдвинутом чанкере даёт moveOther (контроль: сдвиг только memory_version → moveBankOnly) |
| Отказ движка на off-vocabulary ответе классификатора | НЕ сейчас | смена поведения ПЛАТНОГО прогона: пак, называющий типы и не называющий родов, сегодня легален; вынужденная правка промта перекупает classify-фазу (байты промта в RequestHash). Незаказанная смена = мотив, запрещённый D39.183. Строкой бэклога как пред-условие ко второй паре |
⛔ ХОЛОДНЫЙ ПРОГОН НА БОЕВЫХ КОНФИГАХ: НЕ НУЖЕН — и сегодня НЕВОЗМОЖЕН
Невозможен: ls configs/mining-contrast.zh.txt → нет такого файла (контроль: файлов в configs/ — 7). gates.terminology включён в c1 и теперь в обоих армах ⇒ CheckMiningContrast отказывает на пред-полёте до первого платного вызова. Стенда тоже нет: backend/example/chapter1-zh.txt — 641 байт (один чанк, майнить нечего), langpack_root в его book.yaml — 0 хитов при 44 строках; книги в books/ несут пути /home/ubuntu/**, которых на этой машине нет.
Не нужен, потому что заменён поимённо — и всё уже исполнено:
| гейт | что доказывает |
|---|---|
TestGoldenDeterminism зелён против ЗАКОММИЧЕННОГО capture.golden |
18 записанных провайдерских вызовов, обе строки волнового снапшота, каждый request_hash, тела запросов и итоговые тексты — байты не двинулись. Чтение сильнее пере-снятия: пере-снятый голден может согласиться сам с собой мимо репозитория |
make mutations |
14 записей, 14 RED, 0 unexpected, anchors swept: 0 of 225 — включая обе новые движковые гарантии секции proposed и обе гарантии собранной книги |
config.TestAnArmIsTheProductionConfigWithADifferentEditor |
пере-снятые армы == c1 вне блока редактора, по загруженным значениям целиком |
равенство загруженных c1/c2 HEAD↔дерево |
правки в боевых конфигах — только комментарии |
Если владелец всё же хочет живое подтверждение движковой половины — узкая форма, порядок $0.05: развернуть артефакт контраста (jieba 0.42.1 → configs/mining-contrast.zh.txt), НОВЫЙ каталог проекта и новый book_id (чужой стенд не мигрировать), затем tmctl translate --verify-bank --max-units 3 --ceiling-usd 0.10. Проверка после: секция proposed в <project_db>.bank.json непуста, и её длина равна числу N из ШАПКИ .bank-stop.txt, а не wc -l (таблица многострочная на терм). ⚠ Срабатывание --ceiling-usd обрывает прогон в ЧЕРНОВОЙ волне, ДО стопа: деньги потрачены, ответа нет — это «замер не состоялся», а не отрицательный результат.
И главное, почему я против прямо сейчас: прогон ответит ровно на ПОЛОВИНУ вопроса. Вторая половина отвечается за $0 и отвечается «нет»: аллоулист сайдкара платформы знает три ключа, proposed среди них нет (grep -rn 'json:"proposed' platform/ → 0 при 123 json-тегах в platform/internal/ingest), декод нестрогий, секция молча выбрасывается. Экран подписи после лендинга покажет ровно то же, что 04.09. Разрешение на деньги стоит приберечь для окна перенарезки, где двигается адрес главы — там живой прогон отвечает на вопрос, который $0-гейтом не берётся.
Вопросы оркестратору
- Решение по
make mutationsvs внутрьbattery(§4.2в) — размен, а не истина, и он мой. Числа: 2:28 против 3:22, инструмент гоняет пакет БЕЗ-race. Если считаешь, что гейт обязан жить внутри — это одна строка вMakefile. - Снятие
pipeline-arm-deepseek-pro.yaml— исход названный, но необратимый в моей зоне только на словах: файл удалён из дерева, история цела. Если владелец предпочитает «явный алиас с комментарием» — скажи до лендинга, вернуть дешевле, чем потом. - Форма секции
proposedв сайдкаре — моё проектное решение (одиннадцать полей, KWIC и evidence НЕ вошли). Платформа её пока не читает; лучше сверить набор полей ДО того, как начнёт. - Дописки в
docs/BACKLOG.md— две фактические поправки (строки 346 и 350) и одна дописка вdocs/STACK.md, см. раздел пингов. Сама не трогала.
Заявление о завершённости (§13)
- У каждого пункта §4 есть исход — таблица в начале секции, пунктов без исхода нет. §4.7 соблюдён: фикс
第零章не тронут,chunkerVersionне двигался (доказано голденом против ЗАКОММИЧЕННОГО файла). - КРУГИ СОШЛИСЬ на уровне механизма. Восемь кругов: 1 — моя проверка исполнением по ходу; 2–4 — веер
Agent(тесты · боевой код · правки круга 2 · правки круга 3), 22 находки; 5 — воркфлоу по осям владельца, 38 выдержавших из 46; 6 — по правкам круга 5, 15; 7 — по правкам круга 6, 8 при вердикте «лендить можно, блокеров 0»; 8 — по правкам круга 7: находок уровня «механизм врёт или ломается» в движке и гейтах НЕТ, остались восемь строчных, все закрыты. ВСЕ 83 находки — в моей собственной работе. Пять раз подряд лечение предыдущего круга само становилось находкой следующего (ложный якорь$(CURDIR)· ложное-зелёноеReasoningMaxTokens· паникующая индексация · линт, мерящий не тем прибором · страж, закрывающий терминал) — это записано не как курьёз, а как мера того, чего стоит одна правка без проверки исполнением. - Знаменатели названы по каждому классу — отдельная таблица. Два класса я объявляла закрытыми, закрыв их в ОДНОМ носителе из шести и из трёх; оба поймала не я. Столбец «закрыт в N из M» заведён именно поэтому.
- Таблица мутаций полная, выживших нет: 14 записей подмножества, 14 RED,
0 unexpected outcome(s), гниль якорей 0 при 225 записях. Сверх каталога предъявлено исполнением ещё 20+ посадок — каждая с текстом падения. - Числа сняты ПОСЛЕ последней правки и на здоровой машине. ⚠ Два прогона в числа НЕ вошли и названы прямо: один упал по
no space left on device(моя же оснастка забила/tmp), другой был убит системой по нехватке памяти. Падение среды — не результат. - Всё живое — в ДЕРЕВЕ, а не в письме. То, что сознательно НЕ сделано, стоит в §10 с доводом; то, что вне моей зоны, — в пингах с адресами и контрольными величинами.
- Чужих зон не касалась.
platform/,frontend/,eval/,books/,backend/docs/— ноль позиций вgit status;docs/BACKLOG.md,docs/STACK.md,docs/experiments/— только пингами.docs/PROGRESS.md— чистая вставка:git diff --numstatдаёт 502 0, ни одной удалённой строки (числа кругов, которые дофикс пере-снял, правились ВНУТРИ строк, добавленных этой же сессией и ещё не закоммиченных, — чужой хроники это не касается).
Заявляю дословно формулой §13: «работа завершена, править не планирую».
Дерево на момент сдачи
Позиций git status --short backend — 39 (35 изменённых · 1 удалённая · 3 новых файла), плюс docs/PROGRESS.md (эта секция) — моих 40. ⚠ git status печатает 45: остальные 5 позиций в docs/ (BACKLOG.md, STACK.md, architecture/14-api-contract/README.md, architecture/18-bank-ontology.md, product-requirements.md) — НЕ мои, это незакоммиченная работа оркестратора в его зоне; проверено чтением диффа (18-bank-ontology.md подписана «акт лендинга пака «гейт вместо прозы»»). Я их не трогала и не трогаю. Чужих зон (platform/, frontend/, eval/, backend/docs/) не касалась ни одним байтом; docs/BACKLOG.md и docs/STACK.md не трогала — только пингами. НЕ КОММИЧУ — дерево передаётся на лендинг.
Новые файлы: internal/chunk/headingparity_test.go, internal/config/armparity_test.go, internal/pipeline/classifiervocab_test.go. Удалён: configs/pipeline-arm-deepseek-pro.yaml.
ДОФИКС ПОСЛЕ ЛЕНДИНГА — три находки третьего верификатора (08.09, к акту D39.225)
Верификатор шёл по операторской правде и вернулся уже после лендинга: девять находок, шесть я закрыла прежним дофиксом, три пережили коммит. Все три пере-мерены МОИМИ руками — это были его утверждения, не мои замеры, — и все три подтвердились.
F7 — арм-шапка снова называла не то, чем отличается, и это ровно тот класс, ради которого пак существовал. Комментарий обещал «ЕДИНСТВЕННОЕ отличие арма от боевого — эти четыре строки» и перечислял model · prompt_version · temperature · reasoning. Замер диффом против pipeline-c1.yaml (комментарии сняты, сравниваются ЗНАЧЕНИЯ): отличий два — model несёт другого редактора, и строки few_shot: false у арма НЕТ. Три из четырёх названных ключей боевому по значению равны, а пятое, настоящее отличие шапка не считала — при том что его тут же объясняет следующий комментарий. Гейт равенства это поймать не мог и не должен: он сравнивает конфиги, а не прозу о них. Комментарий пере-написан по диффу в обоих армах; пере-замер после правки печатает ровно две строки расхождения, ровно те, что названы.
F9 — snapshot.go: «its four callers» при трёх перечисленных. Замер: вызовов \.snapshotID() — 5, в 4 файлах (контроль: вызовов snapshotIDForWave — 53). Четвёртый файл — runner_test.go:1687, тест TestRunnerSnapshotFoldsClassifierAndLocalTag, пинит версию классификатора и локальный бэкенд-тег. Теперь в комментарии стоят оба числа и назван четвёртый предмет.
F10 — make battery писала .skips.log в РАБОЧЕЕ дерево. Не новая находка: записана 09.08 в docs/architecture/13-tech-debt-anchors.md, Б-122, как не-блокер приёмки пака стандартов — месяц пролежала с носителем. Замер: git check-ignore → не игнорируется; убирается на обоих штатных путях, переживает Ctrl-C. Закрыто В ИСТОЧНИКЕ, а не .gitignore: харвест-лог уехал в mktemp с trap — файла в дереве больше нет вовсе, прятать нечего.
⛔ И собственная проба этой же правки поймала в ней дефект — печатаю, потому что вердикт по цвету от вердикта по тексту отличается только этим. Первая редакция ставила trap 'rm -f "$log"' EXIT INT TERM, как и соседняя цель mutations. Проба SIGINT-ом показала: POSIX-шелл ПРОДОЛЖАЕТ прерванную строку после возврата из обработчика, и цепочка доехала до последнего шага с уже удалённым логом — напечатав (none), то есть «скипов нет», по несостоявшемуся сбору. Тихий скип, читающийся как покрытие, — ровно то, что этот проход и заведён ловить. Обработчик INT/TERM теперь ВЫХОДИТ (exit 130), а не только убирает; та же правка внесена в mutations, где форма была та же. Предъявлено исполнением: прерванный прогон — вывода нет, RC=130, остаточных /tmp/tmp.* 0, мусора в дереве 0; КОНТРОЛЬ на штатном пути — та же цепочка печатает строку --- SKIP и убирает за собой.
Попутно закрыта соседняя дверь того же класса. backend/.gitignore держал одну строку /tmctl — артефакт go build ./cmd/tmctl/, запущенного из корня зоны. Пакетов cmd/ три, и вчерашний tmmutate висел в git status сороковой позицией сдачи. Внесены все три (/tmctl · /tmvet · /tmmutate); проверено git check-ignore: три игнорируются, internal/pipeline/snapshot.go — нет, то есть правило не слишком широкое.
⛔ И ВТОРОЙ дефект в той же правке — его поймал уже гейт, а не проба. Пере-набирая строку mutations под новую форму trap'а, я срезала из неё mkdir "$tmp/backend". make mutations упал за 0,02 с текстом tar: /tmp/tmp.…/backend: Cannot open: No such file or directory — то есть копия не создавалась вовсе, и гейт отказал ДО первой посадки, а не сделал вид, что прошёл. Восстановлено; числа ниже сняты после восстановления. Две правки подряд в одном рецепте, два дефекта — обе поймало ИСПОЛНЕНИЕ, ни одну не поймало перечитывание.
Якоря каталога после правок целы: 225 записей проверено, битых якорей 0 (прибор — тот же счёт вхождений find, что делает посадка).
Числа, снятые ПОСЛЕ восстановления рецепта, ничем после них дерево не тронуто. make mutations → exit 0, 3m52.6s, «14 mutation(s) run, 0 unexpected outcome(s)», 14 RED, anchors swept: 0 of 225 entr(ies) rotten. Затем make battery → exit 0, 3m40.0s, 0 issues, ok 19 / FAIL 0 / «no test files» 4, скипов 4 — те же. Мусора после обоих прогонов: .skips.log в дереве 0, осиротевших /tmp/tmp.* 0 (контроль: файлов в корне зоны 17). Записи ARM-… в подмножестве это касается прямо — она сажается в pipeline-arm-glm.yaml, чью шапку правил F7, и краснеет тем же механизмом, что и до правки.
ВТОРОЙ ДОФИКС ПОСЛЕ ЛЕНДИНГА — живая дыра в починке моей же находки F3 (08.09, к акту D39.225)
Две независимые линзы разными посадками нашли ОДНО: паритет строки предложения сверял два списка ПО ДЛИНЕ, а фикстура давала обоим пустой список и Invented: false. Три сравнения вырождались в 0 != 0 и false != false, а Freq проверялся только на != 0. Пере-мерено моей рукой: четыре мутации разом — Freq*10, Invented := false, Contradicts ↔ BankHolds — пакет ok за 16,8 с. Это D39.208 п.5, воспроизведённый ВНУТРИ фикса моей же находки, и садится он ровно на пару, чьи комментарии в коде объясняют, что «прогон противоречит сам себе» и «книга уже зовёт это иначе» — РАЗНЫЕ решения.
Лечение — разделение работы, а не ещё одно сравнение. Свёртка projectBankProposals — чистая функция, и свойство «ни одно решающее поле не потеряно, не переставлено с соседом и не пере-масштабировано» есть свойство её одной. Она получила собственный тест TestEveryDecidingFieldSurvivesTheProjection (bankexport_test.go) на строке, где КАЖДОЕ поле отличимо от каждого: два списка расходятся и длиной, и содержимым; Freq/Spread/Conf — три разных ненулевых числа; Kind и Channel — две разные строки; рендеринг — тот, которого не предлагал ни один черновик. Плюс рефлективный страж: ни одно поле проекции не осталось нулевым — это ловит поле, ДОБАВЛЕННОЕ к предложению завтра и не заполненное свёрткой. Его границу называю: поле, которое отрастил BankStopRow и которое СЛЕДОВАЛО бы проецировать, механически не ловится — «решающее ли это» есть суждение, и оно принадлежит тому, кто поле добавляет.
Фикстура интеграционного теста пере-сделана невырожденной, и невырожденность УТВЕРЖДАЕТСЯ в нём же. Сид несёт вторую строку — неподписанный 方源 → Странник с until_ch: 20 (идиома TestConsolidationAgainstTheBankIsReportedAtTheStop), отчего у опубликованного предложения непустой bank_holds; роль терминологии возвращает Фан-Юань — рендеринг, которого черновики не предлагали, отчего invented истинно не по случайности. Три стража предпосылки падают с текстом «premise broken», если фикстура перестанет быть той, которую тест описывает.
⛔ И собственная проверка этой починки нашла в ней дыру — печатаю, потому что иначе отчёт был бы чище работы. Первая редакция сверяла секцию файла со свёрткой ТОЙ ЖЕ таблицы, то есть свёртку с самой собой: Freq*10 и своп Kind↔Channel эту сверку пережили — оба берега двигаются вместе. Добавлены якоря ЗНАЧЕНИЙ против самой стоп-строки (Kind/Channel — переименованные соседи одного типа; Freq/Spread/Conf — числа). После этого все пять посадок краснеют, и три — точным текстом с числами (freq=120 … the row counts 12, kind="banknote" channel="name", conf=1 … -1). ⚠ Оставшиеся две ловит СТРАЖ ПРЕДПОСЫЛКИ, а не сравнение: текст говорит «bank_holds пуст и неотличим от contradicts» — это правый вердикт по правой причине, но своп, сохраняющий непустоту обеих сторон, здесь бы уцелел. Он падает на юнит-тесте, где оба списка непусты и различны; разделение названо в комментарии, чтобы следующая смена не приняла интеграционный за сторожа свёртки.
Каталог: 225 → 230 (+5, battery 14 → 19). Четыре записи на свёртку (BANKSTOP-the-sheet-carries-the-rows-own-frequency · BANKSTOP-kind-and-channel-are-not-exchangeable · BANKSTOP-the-two-lists-answer-different-questions · BANKSTOP-an-invented-rendering-is-published-as-invented) и одна на арм-гейт (ниже). Битых якорей после всех правок — 0 при 230 записях.
Латентное — прикрыла, а не отдала строкой. Ничто не утверждало, что редактор боевого конфига НЕ additive-биллинга; переехал бы он туда — изъятие reasoning_max_tokens из арм-паритета начало бы срабатывать МОЛЧА, и единственным следом была бы строка лога, которую на зелёном прогоне не читают. Теперь гейт УТВЕРЖДАЕТ, что изъятие не используется, и падает с текстом, называющим решение. Условие изъятия и условие стража сведены в один предикат forcesReasoningBuffer — две копии одного правила разъезжаются именно в ту сторону, которая важна. Предъявлено ИСПОЛНЕНИЕМ дважды: (1) боевой редактор переведён на grok-4.3 + reasoning_max_tokens (без ключа загрузчик отказывает РАНЬШЕ гейта — первая посадка краснела не тем механизмом) → страж говорит «production now runs editor "grok-4.3" … Decide deliberately»; (2) предикат расширен до != "" → страж срабатывает на боевом deepseek-v4-pro, то есть само условие тоже запинено (запись каталога ARM-the-one-exemption-is-asserted-unused-not-merely-logged). ⚠ Граница: additive_total в предикат НЕ входит намеренно — загрузчик (pipeline.go:771) там ключ тоже не форсирует, и предикат шире правила изымал бы то, чего никто не форсирует.
Числа, снятые ПОСЛЕ последней правки (порядок — сперва мутации, затем батарея; дерево между ними не тронуто). make mutations → exit 0, 5m13.7s, «19 mutation(s) run, 0 unexpected outcome(s)», 19 RED, выживших 0, anchors swept: 0 of 230 entr(ies) rotten. make battery → exit 0, 3m39.4s, 0 issues, ok 19 / FAIL 0 / «no test files» 4, скипов 4 — те же четыре. Подмножество выросло 14 → 19, и цель подорожала 3m52 → 5m13: это по-прежнему «примерно столько же, сколько батарея», и это ровно та причина, по которой в README теперь нет процента.
Две мелочи. snapshot_wave_test.go говорил «four callers», соседний snapshot.go — «five call sites in four test files»: оба верны, единица не названа; теперь единица названа в обоих. backend/README.md печатал диапазон цены гейта 87–104 %, снятый на СТАРОМ составе из 11 записей, и об этом не говорил — пере-снят формулировкой без процента, вместе с отзывом моего же числа «123 %» (см. поправку выше по секции: парный замер спина-к-спине дал 102 %, то есть 123 % были фоновой нагрузкой, а не свойством цели).
ТРЕТИЙ (и по правилу остановки ПОСЛЕДНИЙ) ДОФИКС — порядок секции и «ничего не консолидировано» (08.09, к акту D39.225)
Две линзы независимо нашли две выживших мутации в свёртке предложений. Пере-мерены моей рукой на чистых копиях: разворот порядка — ok 15,8 с; if p.Dst == "" { p.Dst = row.Src } — ok 16,1 с. Обе настоящие, и корень у них один: тест свёртки проецировал ОДНУ строку, поэтому порядок был ненаблюдаем по построению, а фикстуры пакета все несли непустой Dst, поэтому класс «роль не консолидировала ничего» был невидим целиком.
Бьёт это по свойству, которое код объявляет своими словами (bankexport.go: «Order is the stop's own RANKING… which row to read first is the information here») и которое не утверждал ни один тест; и по классу, который комментарий поля называет дословно («"" when nothing was consolidated»). На листе подписи вторая мутация показала бы 青茅山 → 青茅山 — исходную поверхность как рендеринг ровно там, где решения нет.
Лечение. Тест свёртки проецирует ТАБЛИЦУ ИЗ ДВУХ строк в известном ранжировании и сверяет срез целиком, а не найденную перебором строку: позиция — часть утверждения. Вторая строка — та, где роль не решила ничего (Dst: "", Conf: -1 — «роль не назвала уверенности» есть другой факт, чем «уверена на 0 %»). Рефлективный страж нулевых полей остался на ПЕРВОЙ строке и это сказано на месте: вторая полупуста намеренно, в этом её смысл.
И порядок отдельно закреплён в интеграционном — против стоп-СТРОК, а не против свёртки. Сверка «секция есть свёртка той же таблицы» структурно слепа к развороту: оба берега едут вместе. Добавлен цикл, сверяющий i-е опубликованное предложение с i-й строкой стопа, и при расхождении печатающий обе последовательности целиком — «строка 2 не та» без обеих раскладок отправляет читателя в отладчик.
Предъявлено ИСПОЛНЕНИЕМ, по одной посадке на чистой копии: разворот → краснеет НА ОБОИХ уровнях (bankexport_test.go:94 «the projection is not the table it projects» и miningstop_join_test.go:996 «published row 0 is "青茅山", the stop ranked "方源" there»); пустой Dst → краснеет на юнит-тесте. ⚠ Вторую интеграционный НЕ ловит и поймать не может: в его фикстуре нет строки с пустым Dst, а его сверка — свёртка против самой себя. Разделение то же, что и кругом раньше, и названо там же.
Каталог: 230 → 232 (+2, battery 19 → 21): BANKSTOP-the-sheets-order-is-the-stops-ranking и BANKSTOP-nothing-consolidated-is-published-as-nothing. Битых якорей 0 при 232 записях.
Числа, снятые ПОСЛЕ последней правки (порядок — мутации, затем батарея; между ними дерево не тронуто). make mutations → exit 0, 5m39.4s, 21 запись, 21 RED, выживших 0, 0 unexpected outcome(s), anchors swept: 0 of 232 entr(ies) rotten. make battery → exit 0, 3m17.2s, 0 issues, ok 19 / FAIL 0 / «no test files» 4, скипов 4 — те же. Тестов в зоне 1267 (два новых теста свёртки; третий дофикс имён не добавил, он пере-сделал существующий).
⛔ Правило остановки применено оркестратором, и я его принимаю без спора. Три круга подряд находили в одной новой секции всё более узкие вещи; у секции сегодня ноль читателей, и цена следующего круга растёт быстрее, чем то, что он покупает. Найденное после этого дофикса идёт СТРОКОЙ бэклога, а не работой: «контракт секции предложений запинен по полям и порядку, но не исчерпывающе».
Пак «ЗАКОН БАНКА — ЧЕСТНО» (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 находок, все разобраны. Самые дорогие:
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-pathstagerun.go); поймано мутацией — мутант «fast-path обслуживает скипнутые» ПЕРЕЖИЛ пин. Формулировка исправлена наwaverun.go, близнецexport.go(TextModified) приведён в согласие, поставлен пинTestOrdinaryResumeMovesOnlyTheSkippedRow.- Ложное срабатывание, класс A: для сид-поверхности, задетой через banknote, выработка НИКОГДА не ложится (эмиссия её роняет), поэтому мой текст «the term would carry TWO renderings» был ложью ровно на сценарии моего же теста. Проверка пере-сформулирована как разногласие; текст варнинга и док переписаны.
- Ложное срабатывание, класс B: сравнение UNIQUE-кортежа шло по сырым
Src, а banknote-кандидат несёт сырую поверхность против нормализованного ключа ложащейся строки (族長против族长). ⚠ Лечение круга 1 было неверным (свёртка обеих сторон) и переделано на круге 2 — см. §4-бис п.1. - Мой собственный комментарий повторял чужой misnomer: «dropped where a SIGNED row holds the key» —
loadAutoBankроняет предложение по ЛЮБОЙ ранее собранной строке любого статуса. Исправлено и названо ценой пропуска. consolidatedRowsне пиннился ничем: мутации «убратьSinceCh» и «убрать алиасы» переживали весь пакетpipeline. ДобавленTestConsolidatedRowsCarryTheWindowAndTheAliases; обе мутации теперь ловятся с верным текстом.- Три дефекта в моём корпусном приборе: классификация пары по подстроке
: approved "ловила только случай, когда approved-строка печатается первой;booksSeenбыл тождественbooksWithRowsпо построению (мёртвая «контрольная» величина); подсадка строилась отg[0], у которой может не быть огневого ключа или dst ⇒ ложный ОТКАЗ прибора. Все три закрыты, числа после починки те же. - Двойной репорт в ОДНОМ прогоне — подтверждён моим прогоном на ДЕЛЬТА-фикстуре (
test-book.mined-delta.yamlс неподписанной строкой方源→Странник): авто-режим послеwriteAutoBankпере-сидит, иUnverifiedKeyConflictsназывает ту же пару через 2 мс после стадии схлопывания — collapse=1, merge=1, КОНТРОЛЬ всего 3 строки WARN. ⚠ Фикстура названа по находке круга 5: на СИД-фикстуре моего же e2e выходит collapse=1, merge=0, потому что эмиссия роняет предложение по сид-поверхности, и без имени фикстуры число читалось бы как общее. НЕ подавлял: это разные состояния одного термина («роль расходится с банком» до того, как строка легла, и «банк держит обе» после), и только второе означает две строки на проводе. Названо в доке; если оркестратор сочтёт это шумом — резать надо слияние. - Линтер нашёл два настоящих дефекта в приборе: непроверенный
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 я свернула сравнение UNIQUE-кортежа через
NormalizeSourceKeyи написала «схема не даёт обеим строкам существовать». Пере-мерила сама:ReplaceGlossary(族長 + 族长, один sense и окно)→err=nil, rows stored=2; КОНТРОЛЬ с байт-равнымsrc→UNIQUE 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 мутация «свернуть сравнение» ПЕРЕЖИВАЛА весь пакет — фикс был не запинен вовсе. - ⛔
chunkstatus.go— не тот механизм В ТРЕТИЙ РАЗ подряд. Скип в шипящей раскладке (редакторская волна, единица с флагнутым черновиком) пишетrecordSkippedStages, а не флагнутая веткаrunStageSequence: та берётся только при ≥2 стадиях в ОДНОЙ волне. Поймано мутацией — правка веткиrunStageSequenceмой пин ПЕРЕЖИЛА, а правкаrecordSkippedStagesего уронила с верным текстом. Названы оба писателя, в доке пина тоже. - ⛔ Пропуск по кортежу молчит на самой частой форме сид-строки (окно по умолчанию, без sense). Замер: та же фикстура без
until_ch: 20→BankConflicts=0и приdraft, и приapproved; сuntil_ch: 20→ 1. Мой же e2e-тест обходил это подобранным окном, и я этого не вынесла. На провод не влияет (предложение отбрасывается), теряется строка на листе подписи. Названо ценой в докеConsolidationKeyConflictsи вынесено в §5а №7. - Тихий ноль, внесённый ЭТИМ паком:
glossaryRowsвозвращалnilпри ошибке чтения банка без единого слова, из-за чегоBankConflicts=0неотличим от «конфликтов нет». Теперь логируется явно, с формулировкой «их нули означают „не спросили“, а не „не нашли“». - Перебор в §4.3: «ноль confirmed-промахов = подписанная половина исполнена» — неточно:
Confirmedтребует иapproved, и ДОВЕРЕННОГО ключа, а промах на одно-Han ключе демотируется вUnverified. Приведено к «подписанные строки, сработавшие на доверенном ключе». - Стиль (правило владельца): довод «containment + equal-source + approved-only» стоял ТРИЖДЫ — оставлен там, где живёт проверка, остальные заменены ссылкой; снята история в тесте («эта фикстура всегда несла»), план в коде («carry stays unbuilt until it is»), чужой замер 1962/2283 атрибутирован стенд-книге и дополнен
file:lineобоих механизмов. Проверяющий отдельно искал ПОТЕРЮ нужной детали при сокращении и не нашёл (перечитаны все 14 файлов диффа). - §5а вырос с 6 позиций до 9: №6
bankmaterialize.go:127(та же ложь про «signed»), №7 пропуск по кортежу на форме сид-строки по умолчанию, №9 — путь записи статуса не читается по коду (писателей два, выбор решает раскладка волны). Тихий нольglossaryRowsне вынесен, а ЗАКРЫТ. - Подтверждено круга-2 замером: довод про двойной репорт верен по коду (
mining.go:241-246); корпусный прибор после починки даёт те же числа и симметричную классификацию; обе мутацииconsolidatedRowsловятся; ассерт «0 против 2» различает случаи.
⇒ Итог по кругам: 18 находок в круге 1 + 8 в круге 2, из них ПЯТЬ — ложные утверждения в моих же комментариях. Это тот самый класс, который пак чинил, и он воспроизвёлся на мне пять раз. Единственное, что его ловило надёжно, — мутация, прочитанная ПО ТЕКСТУ: три раза пин переживал мутацию, и каждый раз это означало не дыру в пине, а неверный механизм в моём описании.
4-кватер. КРУГ 3 — РЕГРЕСС от моего же лечения круга 2, плюс четыре мелочи
Круг 3 подтвердил, что все шесть находок круга 2 закрыты, и нашёл одну новую — самую дорогую в паке, потому что её внесла МОЯ ПРАВКА:
- ⛔ РЕГРЕСС: метка листа подписи терялась ровно у той популяции, ради которой правка делалась. Лечение круга 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:[]}». - Отчёт §3(а) описывал отменённую версию кода («сравнение свёрнуто через
NormalizeSourceKey»). Приведён к коду; греп отозванной фразы → 0 при контроле 1. - Нумерация §5а шла 1..7, 9, 8 — выправлена.
- Два абзаца доки
ConsolidationKeyConflictsносили один заголовок «Cost of the skip» и читались как дубль, хотя это разные цены. Разведены: «WHAT THE SKIP HIDES» (форма сид-строки по умолчанию) и «WHO RESOLVES A SKIPPED PAIR» (loadAutoBankроняет по строке любого статуса). - Варнинг
glossaryRowsобещал молчание обеих проверок, хотя изscoreOptsзатрагивается только якорь скоринга, и при стойкой ошибке чтения печатается трижды за роль. Текст сужен до «whatever this call feeds», повторяемость названа.
⇒ Урок круга 3, который дороже самой находки: правка, сделанная ПО находке ревью, — такой же новый код, как всякий другой, и требует своего пина. Мой фикс круга 2 был верен по существу и сломал доставку на этаж выше, потому что я запинила изменённую функцию, а не путь до потребителя.
4-квинтус. КРУГ 4 — зеркало того же шва плюс асимметрия доставки
Круг 4 подтвердил все пять пунктов круга 3 закрытыми и нашёл четыре новых. Главная — того же класса, что регресс круга 3, но с другой стороны шва:
- ⛔ Сторона ЗАПИСИ карты
BankHoldsне была запинена вовсе. Мутации ключа записи наcf.Key(firing-ключ, может быть АЛИАСОМ) и наcf.BankSrc(поверхность строки банка) переживали весь пакетpipeline. Причина названа точно: мой юнит-пин строил карту СВОЕЙ копией продакшн-цикла, а не звал продакшн-писателя, а e2e-пин стоит на方源, где ключ кандидата, сырая поверхность, firing-ключ и поверхность строки банка — одна и та же строка, так что любой из четырёх ключей проходил. Вылечено выделением одного писателяbankHoldsByCandidate, которого зовут и продакшн, и пин; фикстура подобрана так, что все четыре строки различаются. Обе мутации красны с верным текстом. - Стдаут-таблица стопа печатала
⚠ contradicts:и НЕ печатала маркер банка (cmd/tmctl/render.go) — оператор на первом экране видел одно разногласие и не видел второго, при том что пак сам обосновал их равенство. Добавлена строка⚠ bank holds:рядом с братом. - Абзац «WHO RESOLVES A SKIPPED PAIR» смешивал две популяции и утверждал «nothing reporting it». По коду: для СИД-поверхности резолвер — фильтр эмиссии (
reverseSectionTerms), а неloadAutoBank; для ДЕЛЬТА-строки —loadAutoBank, и дроп ЛОГИРУЕТСЯ, но текстом «held by a signed term» при любом статусе держателя, то есть оператору говорят НЕВЕРНОЕ, а не ничего. Абзац разведён, §5а №1 отчёта приведён к этому же. - Дока поля
BankHoldsговорила «per candidate src», а комментарий писателя — «keyed by the KEY»: два комментария к одному полю расходились ровно в том слове, на котором сломался круг 3. Сведены.
Плюс два числа отчёта не воспроизводились и были пере-сняты: счётчик ссылок на BankHolds устарел после продления пина, а контрольная формулировка «Contradicts дальше листа и лога не идёт» оказалась ложной — он печатается в стдаут, и именно эта находка привела к п.2.
⇒ Урок круга 4: тест, который ВОСПРОИЗВОДИТ продакшн-логику копией вместо вызова, пинит собственный цикл, а не код. Два круга подряд дыра сидела на одном шве «писатель ↔ читатель», и оба раза её прятала фикстура, где все кандидаты на ключ совпадают.
4-секстус. КРУГ 5 — сошлись по ПОВЕДЕНИЮ; остаток был в пинах и тексте, и шов убран целиком
Круг 5 подтвердил: регресса в лечении круга 4 нет, все пять пунктов закрыты и воспроизведены исполнением (включая замер, которого я не сделала сама на круге 1 — дроп дельта-строки действительно логируется словом «signed» при держателе status=draft). Остаточных находок четыре, все в пинах и тексте:
- ⛔ Шов «писатель ↔ читатель» бил ТРИ круга подряд, поэтому убран, а не подпёрт четвёртой заплатой. Круг 5 показал, что даже после выделения общего писателя мутация «продакшн обходит писателя и вписывает свой ключ» переживает весь пакет: e2e стоит на
方源, где ключ кандидата, сырая поверхность, firing-ключ и поверхность строки банка — одна строка. Решение поD39.216: карты больше нет.terminologyResult.BankHoldRowsнесёт находки НЕГРУППИРОВАННЫМИ, сопоставляет их с рядом одна функцияbankHoldLabelsв том файле, который их потребляет, — то есть ключ выбирается в ОДНОМ месте, а не по разу с каждой стороны. Три мутации ключа сопоставления (cf.Key == c.Key,cf.Src == c.Src,cf.BankSrc == c.Key) теперь красны на одном пине с текстом про сломанное. - Строка
⚠ bank holds:в стдауте была без пина — и её брат⚠ contradicts:тоже. ДобавленTestRenderSignatureStopShowsBothDisagreements; обе мутации (удалить любой из двух блоков) красны, контроль — ряд без маркеров не печатает ни одного. - Абзац доки обобщал дельту: до
loadAutoBankдоходит только НЕПОДПИСАННАЯ дельта-строка, потому что approved-дельта остаётся сид-поверхностью для эмиссии (unsignedEngineSurfaces). Уточнено одним словом. - Корпусный прибор проходил на пустом обходе (
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-lint → 0 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 различных.
Новых находок в коде пака нет. Осталось два:
- Шов-БЛИЗНЕЦ в коде, который пак не трогал:
ContradictionsиConfпересекают ту же границу тем же способом, стороны согласованы, но ни одна фикстура не имеет кандидата сKey != Src— мутация любого из трёх ключей переживает полные пакетыpipeline,terminologyиtmctl. Не регресс и не мой код; вынесен §5а №10. - Два счётчика отчёта снова протухли — третий раз подряд, и причина не в счёте, а в порядке: я снимала числа до правок. Закрыто иначе, чем прежде: все числа отчёта пере-сняты ОДНИМ проходом после последней правки кода, и это записано рядом с ними.
⚠ Круг 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 battery→MAKE_EXIT=0,okпакетов 19 (+4 без тестов), строкFAIL0, линтер0 issues.; скипов 4, все названы батареей:TestMinerFullBookParity,TestCorpusBankKeyConflicts(мой opt-in прибор — батарея его видит и называет),TestHelperEventsRun,TestHelperKillLoop. - Дифф тестов исполнением (
git diff -- 'backend/*_test.go' | grep '^[-+]func Test'): в отслеживаемых файлах добавлено 9, удалено 0;func Fuzz0/0. Плюс по 1 в двух новых файлах (bankconflict_corpus_test.go,resume_updatedat_test.go) → итого +11 / −0. - Детерминизм: 200 прогонов на одном входе — различных выводов
UnverifiedKeyConflicts1,ConsolidationKeyConflicts1; КОНТРОЛЬ — заведомо 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' -v→ 14 PASS, 0 FAIL;go test ./internal/membank/ -run 'TestMemoryVersion|TestMaterializeMemoryVersion' -v→ 5 PASS, 0 FAIL. - Новое поле листа подписи доходит ровно до ДВУХ человеческих поверхностей — сайдкара и стдаут-таблицы стопа: не-тестовых читателей
BankHolds2 (mining.go→renderBankStopTable,cmd/tmctl/render.go). Ссылок всего:BankHolds12 в 4 файлах,BankHoldRows(носитель через границу) 5 в 3; КОНТРОЛЬ — у соседнегоContradicts11 в 4. ⚠ Прежняя формулировка этого контроля («Contradictsдальше листа и лога не идёт») была НЕВЕРНА и снята по находке круга 4: он печатается в стдаут, и из-за той же находки мой маркер теперь стоит там же. ⚠ Числа пере-сняты одним проходом ПОСЛЕ последней правки: круги 4, 5 и 6 подряд ловили в отчёте протухшие счётчики, потому что я снимала их до правок, а не после. - Отдельным пином: диагностика НЕ входит в подписной документ (в
signature mapнет ни маркера, ни ярлыка строки банка; КОНТРОЛЬ — тот же файл содержит青茅山иterms:). - Обе проверки — только
WarnContext; ни одна не возвращает ошибку и не меняет содержимого банка. Отказ (drop/stop) НЕ построен (П2).
8. §5а — «задумано против сделано». НЕ чинил, выношу списком
mining.go:654loadAutoBank(signed []store.GlossaryEntry), зовётся какr.loadAutoBank(in.entries)(bankmaterialize.go:125). Обещано именем параметра, докой (:648) и сообщением оператору (:691«key held by the signed %q→%q»), что предложение движка отбрасывает ПОДПИСЬ. Исполняется: популяция — сид+ruby+дельта любого статуса; неподписанная строка отбрасывает предложение и печатается оператору как «the signed». ⚠ Формулировка круга 1 «ни одна проверка не говорит ни слова» ОПРОВЕРГНУТА кругом 4 и снята: дроп ЛОГИРУЕТСЯ (gatherBankInputs→seeding.go), но текстом «held by a signed term» каким бы ни был статус держателя, — то есть оператору говорят НЕВЕРНОЕ, а не ничего, и это ровно предмет позиции. ⚠ Атрибутирую, а не присваиваю: своим прогоном исходный случай я не воспроизвела — моя фикстура наsince_ch: 0дала РАЗНЫЕ кортежи (обе строки легли, обе проверки сработали:BankConflicts=1, collapse=1, merge=1), а вторая итерация упёрлась в гейт пере-оплаты, потому что переиспользовала тот же проект. Проверено мной только по коду:heldвloadAutoBankстроится из параметра, которым передаётсяin.entries(bankmaterialize.go:125), то есть из строк ЛЮБОГО статуса.terminology.go:873и:941— обе канон-проверки пропускают пару с РАВНЫМИ источниками. Проверочную половину закрыл сегодня; якорная осталась: роль не показывают, как книга уже зовёт поверхность, которую её просят перевести. Это меняет содержимое запроса ⇒ хеш ⇒ деньги, в пак не входит.terminologist.go:257противmining.go:553— фильтр «поверхность уже в банке» стоит только на ЭМИССИИ. Роль и классификатор ОПЛАЧИВАЮТСЯ за поверхности, которые банк уже несёт.bankmaterialize.go:139-141— комментарий на вызове говорит «two DIFFERENT approved terms», тогда какApprovedSharedKeyCollisionsсобственной докой заявляет, что same-src пары не пропускает.mempostcheck.go:91против:122и:130— докаShownговорит «how many unsigned rows were actually PUT IN FRONT of the model here», а sticky-переносcontinue-ится ДО счётчика. Имя метрики шире её смысла.internal/pipeline/bankmaterialize.go:132— remark оператору «auto-bank rows dropped: their key is already held by a signed term (the signed term wins)». Та же ложь, что вloadAutoBank: держателем ключа может быть неподписанная строка, и оператор увидит её названной подписанной.internal/membank/memseed.go, пропуск по UNIQUE-кортежу — сид-строка с окном ПО УМОЛЧАНИЮ и без sense делит кортеж с banknote-предложением (у обоихsince_ch 0), поэтому самая частая форма рукописной сид-строки против выработки роли молчит, каким бы ни был её статус. Замер круга 2: та же фикстура безuntil_ch: 20→BankConflicts=0и приdraft, и приapproved; сuntil_ch: 20→ 1. На провод это не влияет (предложение отбрасывается, двух форм там нет) — теряется строка на ЛИСТЕ ПОДПИСИ. Закрытие требует правила «заменённая строка движка против отброшенного предложения», а колонкаSourceего не даёт: дельта владельца и авто-банк движка обе читаютсяmined.- Пины на операторские сообщения есть, но узкие и несистемные — носитель
internal/pipeline/seeding.go:73. Текст варнинга S14 был закрыт ПОДСТРОКОЙ вpipeline.TestUnsignedConflictIsReportedByTheRun, и расширение правила его честно покраснило; но подстрока стерегла одно словосочетание из всего сообщения, поэтому локализующая половина (обе строки, оба окна, firing-ключ) не была закрыта ничем и появилась только этим паком. ⚠ Прежняя формулировка этой позиции («не был закрыт ни одним тестом,grep= 0») была НЕВЕРНА и снята приёмкой: греп искал целую фразу, живущую только в самомseeding.go. Класс остаётся, но он про ПОЛНОТУ пина на текст, а не про его отсутствие. 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), а этот выношу, потому что он того же класса и чинится десятью строками рядом с существующим тестом.internal/store/chunkstatus.goвместе сinternal/pipeline/waverun.go— ПУТЬ ЗАПИСИ СТАТУСА НЕ ЧИТАЕТСЯ ПО КОДУ, и это свойство места, а не невнимательность автора. Писателей скипнутой строки ДВА, и какой сработает, решает раскладка волны:recordSkippedStages(waverun.go) — для флагнутой РЕДАКТОРСКОЙ единицы, флагнутая веткаrunStageSequence(там же) — когда в ОДНОЙ волне две и более стадии. Читающийchunkstatus.goне видит ни того, ни другого. Замер: три формулировки механизма подряд оказались неверными (в дереве до пака, в моей первой правке, в моей второй), и каждую поймала только мутация — прочитанная по тексту, а не по цвету.
9. Правки существующих тестов, вызванные ЗАКАЗАННОЙ сменой поведения (D39.183)
Расширение UnverifiedKeyConflicts заказано оркестратором (П1), поэтому два теста, описывавших прежнее поведение, — обслуживание, а не подгонка. Оба объявляю:
membank.TestUnverifiedKeyConflictsутверждалlen(got) != 1. Теперь 2, и второе нашлось В ЕГО ЖЕ ФИКСТУРЕ, лежащей в дереве с написания:draft «старейшина»противauto «глава клана»— пара неподписанных, которую никто не видел. Прежняя гарантия сохранена дословно; добавлены обе подписи, оба окна и firing-ключ в каждом сообщении, исключение approved×approved с контролем, «пара с двумя ключами — одна поимка».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. Что я сам считаю слабым местом
- Три круга самопроверки нашли 31 находку В МОЕЙ РАБОТЕ. Пять — ложные утверждения в комментариях, то есть ровно тот дефект, который пак чинил;
chunkstatus.goя написала неверно ТРИЖДЫ подряд (сначала «резюм не пишет», потом верное «пишет» с неверным механизмом, потом со вторым неверным), и каждый раз ловила только мутация, прочитанная по ТЕКСТУ. Вывод для приёмки: мои утверждения о поведении надо проверять исполнением так же, как чужие. ⛔ И отдельно самое неприятное: одну находку внесла МОЯ ЖЕ ПРАВКА ПО НАХОДКЕ — фикс круга 2 был верен в функции и сломал доставку этажом выше, потому что я запинила изменённую функцию, а не путь до потребителя. Правка по ревью — такой же новый код, как всякий другой. ConsolidationKeyConflictsи расширеннаяUnverifiedKeyConflictsчастично перекрываются, и это теперь ИЗМЕРЕНО (§4 п.7), а не предположено. Довод в пользу двух мест реальный (разные популяции), но «одно знание — один носитель» соблюдено не идеально.- ⛔ Мой довод про UNIQUE был ЛОЖЕН, и выяснилось это только на круге 2 — прогоном, которого я на круге 1 не сделала. Я сослалась на схему вместо того, чтобы её спросить; схема ответила иначе (ключ сырой, трад/упрощённая пара — две законные строки, обе инжектятся). Урок шире места: формула «доказано схемой» стояла в моём отчёте там, где честно было «не мерено».
- Мой e2e-тест обходил дыру подобранным значением:
until_ch: 20уводит сид-строку с кортежа предложения, без него проверка молчит (§5а №7). Это тот же класс, что «тест утверждает не то, что думает», и вынести подобранное окно должна была я, а вынес круг 2. Плюс маркер предъявлен на кандидате, которого в подписном документе НЕТ (方源— сид-поверхность): адрес верный (стоп-таблица содержит всех кандидатов), но случай «противоречие у термина, который владелец реально подписывает» отдельным тестом не покрыт. - Комментарий в
waverun.goцитирует ЧУЖОЙ замер (1962/2283, строка 321). Не воспроизводил — атрибутировал. - Три из девяти пунктов §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-тер. Заявление о завершённости
Работа завершена, править больше не планирую. Критерий проверяется механически:
- Исход у каждого пункта заказа — таблица §0, пунктов без исхода нет.
- Круги сошлись, и приёмка добавила три пункта дофикса — все закрыты (§4-октавус). Круг 6 дал «сошлись»; всё найденное кругами 1–6 и приёмкой закрыто поимённо таблицей §4-тер. Два остатка круга 6 не в коде пака: пред-существующий шов-близнец вынесен §5а №10, счётчики пере-сняты.
- Числа сняты после последней правки, каждое командой. Батарея
MAKE_EXIT=0(19 пакетовok, 0 красных, линтер0 issues., 4 названных скипа); что она позже последнего касания кода — предъявлено:find backend -name '*.go' -newer <лог>→ 0 при контроле 3, и с тех пор изменён толькоdocs/PROGRESS.md. - Мутации — таблица §5 полна (23 строк), выжившие названы отдельной таблицей «зелено ДО → красно ПОСЛЕ», отброшенная названа с причиной.
- Обещаний в отчёте нет — всё, что «надо бы», стоит секцией предложений ниже и решается оркестратором.
- Всё живое в дереве — отчёт, таблицы, замеры, ограничения; письма носителем не считаю.
- Дерево в безопасной точке — только моя зона, индекс пуст, не закоммичено, статус приложен выше.
12. Предложения (решает оркестратор, в паке НЕ сделано)
- Подавлять ли повторный репорт пары на ре-сиде в авто-режиме (§4 п.7). Резать надо слияние, не схлопывание.
- Показывать роли существующую форму поверхности (§5а №2, якорная половина) — меняет запрос и деньги.
- Фильтровать кандидатов роли по банк-поверхностям (§5а №3) — снимает оплату за уже банкованные термины.
- Ставить пины на ТЕКСТЫ операторских сообщений (§5а №8) — сегодня их нет системно, и расширение правила сделало один из них ложным при полностью зелёной батарее.
- Запинить шов-близнец
Contradictions/Conf(§5а №10) — десять строк рядом с существующим тестом, фикстура с кандидатомKey != Src. Мой собственный такой же шов ловился ТРИ круга подряд, и это единственная причина, по которой я его называю: цена дыры измерена на себе. - Довести разногласие до листа подписи и на форме сид-строки по умолчанию (§5а №7). Требует правила «заменённая строка движка против отброшенного предложения»; колонка
Sourceего не даёт, потому что дельта владельца и авто-банк движка обе читаютсяmined. Это самая частая форма сид-строки, так что цена молчания не маргинальна.
⚠ ПИНГ ОРКЕСТРАТОРА 06.09 — мелочь, у которой не было носителя, и потому она здесь. backend/internal/bookfile/model.go:59 разросся до 183 знаков — единственная строка длиннее 120 в файле; удлинил её текст комментария, заландженный f1e9226. Правка на строку, линтер молчит, срочности нет. Записано потому, что моё решение «поправит зона при следующем касании» само носителя не имело, а следующего касания может не быть годами — и это ровно тот класс, который смена 06.09 ловила пять раз (находка, живущая только в письме). Возьми при любом касании файла; отдельного захода не стоит.
✅ ПИНГ ОРКЕСТРАТОРА №22 от 05.09 про якоря — ИСЧЕРПАН В ТОТ ЖЕ ДЕНЬ, работать по нему НЕ НАДО.
Зона починила всё коммитом e7d6b3f: counts.py --lint → 0 битых якорей, сверяемых по токену стало 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.⚠ Прожитая проза зоны за 24–31.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:0 → c3aa4cbbb53de134: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_keye996b9d4f129006e9faa6237fb1635a82e32c06c056b195072fae15f582021f6и ТОТ ЖЕunit.idf8ad8c8f114997c5:3d2213f2:0(средний сегмент —cutTag). ⇒ пере-чеканкиunit.idнет,recutу платформы не сработает,unit_resolutionsкниги параллельного платного прогона целы.Состояние: пять пунктов из шести закрыты, шестой (140) упёрся в факт развёртывания и вынесен решением оркестратору — см. §4. Дерево НЕ закоммичено, лендинг за оркестратором.
Батарея (предусловие, не отчёт). cd backend && make battery → MAKE_EXIT=0, golangci-lint 0 issues, ok в 19 пакетах, SKIP три и те же: TestMinerFullBookParity, TestHelperEventsRun, TestHelperKillLoop.
Тесты. grep -rn '^func Test' backend --include=*_test.go | wc -l → 1105 → 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.Gender → DeltaFile → сид-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 БД стенда, через СОБСТВЕННУЮ предобработку движка (splitBanknote → checks.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 (заведена оркестратором).
Два гарда, которые делают «настроено и мертво» невозможным — и оба нашлись не по заказу, а по разбору:
- Загрузка отказывает, если гейт включён, а
mining.contrast_pathПУСТ (internal/config/pipeline.go) — тот же класс «гейт, который не может выстрелить», который лоадер ловит везде. - Наличие ФАЙЛА проверяется на ПИШУЩЕМ пути, рядом с
CheckKeys(Pipeline.CheckMiningContrast, вызов вopenRunnerвнутриforWrite). Место выбрано не случайно:os.Openвнутри прогона стоит ПОСЛЕ оплаченной черновой волны, то есть развёртывание, забывшее артефакт, платило бы за волну, чтобы это узнать. $0-поверхности не трогаются (D20.4). - ⚠ ТРЕТИЙ гард добавлен по находке адверсариального прохода, и он закрывает дыру в моих же первых двух. У раннего возврата ДВА условия, и я гейтил только одно:
r.pack == nil— а нил-пак книга получает, если не объявилаlangpack_rootвовсе или объявила корень без каталога своей пары («nil-and-run»). Такая книга могла нести полностью настроенный и забюджетированный контур и не исполнить из него ни строки. Конфиг-лоадер этого структурно не видит: гейт знает пайплайн, пак знает книга, и вместе они есть только в раннере. Отказ добавлен там, тоже только на пишущем пути.
Пункт 5 — строка 184(а): жанр выкинут. ЗАКРЫТ
grep -rl '{{genre}}' backend/prompts/ | wc -l → 6 → 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-reflow → v2-reflow-nogenre, v3-discourse-reflow → v4-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 > 0 → Carried > 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 -l → 1105 → 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, с заданием ФАЛЬСИФИЦИРОВАТЬ шесть заявлений каждый (деньги и провод · вердикты и данные). Ноль не декларирую: они принесли шесть находок, и четыре я починил.
Находки собственного адверсариального прохода — что нашли и что с этим стало:
- ⛔
bank-applyСТИРАЛ произведённый род — то есть ровно тот акт, ради которого стоп существует.termFromBankкопировал толькоTypeиAliases; строка дельты уходила сgender: "", аloadAutoBankпотом ронял авто-строку как занятый ключ. ПОЧИНЕНО: род переносится вперёд, как переносятся алиасы (это находка движка ОБ СУЩНОСТИ, а решение о РЕНДЕРИНГЕ не просили её выбрасывать); дверь по-прежнему род не ПРИНИМАЕТ. ПинTestApprovingATermKeepsTheGenderTheEngineProduced, проверен красным на копии без правки. - ⛔ Мой первый гард пункта 4 закрывал только одно из ДВУХ условий раннего возврата. Второе —
r.pack == nil, а нил-пак книга получает безlangpack_rootили с корнем без каталога своей пары. Такая книга несла бы настроенный и забюджетированный контур и не исполнила бы ни строки. ПОЧИНЕНО третьим гардом в раннере (пишущий путь), где гейт и пак есть вместе — конфиг-лоадер этого структурно не видит. - ⛔
repairReGateзвалclassifyБЕЗTargetScripts— экран цели на пути ремонта воздерживался, судя везде: починка, вернувшаяся на другом языке, прошла бы ре-гейт, вся работа которого в том, чтобы спросить «это всё ещё пригодный ответ». ПОЧИНЕНО: ре-гейт зовёт тот же классификатор с теми же входами. - ⛔
classify_budget_usd: 0.50давал запас 1.45×, а комментарий рядом обещал «≈3×». ПОЧИНЕНО: 1.00, запас 2.9×, и названо, что по замеру классификатор ДОРОЖЕ рендера. - ⛔ Тест
TestTheLiveEchoGateKeepsItsMeasuredMarginпроходил на фикстуре с ПУСТЫМ off-target классом:0/0= NaN, а любое сравнение с NaN ложно. ПОЧИНЕНО знаменателем-предусловием. Тем же касанием: суррогат целевой стороны привязан к записанному счёту (как уже был исходный), добавлены проверкаtarget_script_letters ≤ lettersиTestTheScreenConstantsStillSitWhereTheCorpusPutThem— константыlangscreenсверяются с ДАННЫМИ, а не с константами (порог обязан лежать в пустом интервале корпуса, пол улики — не выше самого короткого off-target). - ⚠
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 мс — то есть запрос был выпущен и, скорее всего, оплачен. Латентность разводит два случая (20–31 мс против 156 с). Я это НЕ чинил:stagerun.goв моей зоне, но это ДЕНЕЖНЫЙ путь и отдельный предмет, а не пункт вайр-батча. Заказ на него — отдельным паком.
ЧЕГО Я НЕ ДЕЛАЛ ПО ГРАНИЦАМ: не коммитил, индекс и историю не трогал; platform/ и eval/ только читал; соседний worktree не открывал; .env не читал.
ДОФИКС ПО ПРИЁМКЕ (04.09) — четыре пункта наряда, все закрыты
⚠ Класс, который приёмка вскрыла и которого моя самопроверка не нашла: СЕМЬ ЗАЯВЛЕННЫХ ГАРАНТИЙ СУЩЕСТВОВАЛИ ТОЛЬКО КАК КОД. Двенадцать её посадок пережили полную батарею. Это ровно образец D39.187 — тот же дефект, что этот пак чинил у чужого пака, повторённый мной. И нашёлся он там, где я сам сказал «ставь гуще», то есть карта слепых зон работает; чего у меня не было — это привычки сажать мутации на СВОЙ новый код, а не только на соседний.
Д1 — пять неприбитых гарантий прибиты, каждая тестом И записью каталога (WB5–WB13, каталог 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 -l → 27.
⚠ Заказанная смена поведения, объявляю (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, записи WB1–WB13 красные.
КРУГ 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, записи WB1–WB29 красные одним прогоном. Удалённых имён по-прежнему одно — переименование 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 посадок). Подпись — это СТАТУС, а не уверенность матча: подписанная строка, сработавшая по сомнительному ключу, всё равно канон, которому уступают. Ключевание набора подписей на диспозиции пережило. Уступать должен ЛЮБОЙ неподписанный статус, а не только draft — auto пишет майнер, то есть ровно та строка, ради подчинения которой правило и существует. Плюс: подписанная строка с ПУСТЫМ переводом не канон (иначе термин исчезает из блока), несимметричный 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. Протухли четыре МОИ ЖЕ записи, чьи якоря увезли рефакторы кругов 2–3: 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НЕ трогаю: правка данных двигаетEmbeddedVersion→cutTag→manifest_key→ сносunit_resolutionsкниги ПАРАЛЛЕЛЬНОГО платного прогона платформы. Что НЕ делаю. Чужие зоныplatform/frontend/eval/и соседний worktree. Строки 131 · 105(а) · 14 · 119 · 124 · 115 · 160 · 161 · 142. Самопроверка исполнением. Дифф^func Testпофамильно до/после (удалённых имён 0) · маскированный дифф голдена (только названные версионные оси + ровно две строки диспозиций) · собственные посадкиtmmutateВНЕ шести пунктов на копии дерева · отдельный адверсариальный проход свежим контекстом (модель назову) · отчёт о движенииcutTag:tmctl manifestдо и после.
02.09 — эхо-записка пака «число согласия на пути второй покупки» (промт BACKEND_CONSENT_SESSION_PROMPT.md, сессия textmachine-77)
Канала к оркестратору нет: адрес в
/tmp/textmachine-channel(textmachine-33) вListAgentsотсутствует, промт писан на другой машине — вопросы едут секцией отчёта ниже. Дерево на входе чисто, HEAD494c4ef; все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на копии до и на дереве после.
03.09 — ОТЧЁТ пака «число согласия на пути второй покупки» (сессия textmachine-77, промт BACKEND_CONSENT_SESSION_PROMPT.md)
Итог: четыре пункта состава исполнены, дерево
backend/готово к лендингу, НЕ КОММИЧУ (git diff --cached --name-only→ пусто). HEAD на входе494c4ef; после согласованного с платформой (textmachine-37)git pull --ff-only—2a63c37. Входящее (72 файла) не пересекалось ни с одним моим файлом, кромеdocs/PROGRESS.md: свою записку сняла редактором, дала git пройти fast-forward, вернула. Индекс не трогала, stash не применяла. Канала к оркестратору нет:textmachine-33вListAgentsотсутствует, промт писан на другой машине — вопросы секцией ниже. Всеfile:line-якоря промта сверены грепом здесь и сошлись. Батарея на финальном дереве:cd backend && make battery→MAKE_EXIT=0,golangci-lint0 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 -l→ 1083 → 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 -l→ 1 ⚠ (в первой редакции отчёта стояло «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и здесь:- «первая редакторская стадия» (остаток, который промт велел назвать): конвейер, получающий ПЕРВУЮ редакторскую стадию, двигает отгружающую волну с draft на edit, и уже прочитанные юниты репортятся свежими. Закрытие требует записи о том, ЧЕМ БЫЛА отгружающая волна.
- Прерванная ПЕРЕ-ДЕЛКА — новый остаток, найденный этим паком. Отгруженный юнит, чья пере-делка оборвана между волнами, имеет строку в КАЖДОЙ позиции, снова классифицируется
unitReworkи снова берёт слот. Отличить его от обычного банк-онли сдвига (черновик free, редактор пере-оплачивается — определение rework) можно только записью «какой прогон купил какую строку». Строку 232 закрываю только по остатку «слот», как и велено.
3. ФЧ-4 — ОБЕ половины, фигура едет с базисом (D39.181 п.1).
- (а)
HistoricalRowsбольше не теряется на границеstatus.go:rebillOutcomeвозвращает проекцию ЦЕЛИКОМ (подnone/failed— нулевую структуру, так что новое поле не может пережить «неизвестный» ответ, забытое в одной ветке), вStatusReport—rebill_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.
Мандат самопроверки — три артефакта.
- Дифф
^func Testисполнением: 1083 → 1102, удалённых 0, добавленных 19. - Собственные адверсариальные посадки ВНЕ трёх гарантий: каталоги
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. - Проход по СВОЕЙ готовой работе свежим контекстом. Воркфлоу из семи линз (направление ошибки · раскрытие на новой границе · слот и черновой конвейер · вывод членства
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нижеCarried—granted()уходил в минус, строка стопа говорила «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».
- [HIGH] перенос без границы обнулял потолок — грант 1 оплачивал 5 юнитов, и прогон об этом молчал. Введена граница
Три оси ревью, названные промтом уязвимыми именно в этом паке — по каждой предъявляю.
- Направление ошибки. Двойной счёт искала специально: порог сравнивает базу и сумму, посчитанные ОДНИМ
usd()(тест сверяетprojected_book_usd, а не только сумму), максимум из двух цен берётся РОВНО один раз на вызов, добавка денег банк-ролей входит в опубликованную проекцию и НЕ входит в базу порога — как ратифицировано. Перелёт порога проверен с обеих сторон: число выросло там, где занижало, и не упало там, где стадия ушла на дешёвую модель. Одну форму двойного счёта ревью всё же нашло — кратность оценки $0-строки; направление у неё безопасное (завышение), ограничение названо вслух и в коде, и в секции «не проверено». HistoricalRowsна новой границе. Не теряется и не удваивается: единственный инкремент на строку,rebillOutcomeотдаёт проекцию целиком, под «неизвестно» — нулевую структуру. Текст отказа и--jsonназывают ОДНО число с ОДНИМ базисом — это утверждает тест, сравнивающий подстрокуRebillFigureBasis()внутри текста отказа, а не два независимых ожидания.- Слот гранта на черновом-только конвейере. Проверено исполнением, а не рассуждением:
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) — записываю, чтобы решения не пере-открывались.
- Поле
carriedв кадреfinishedшва (runevents.VolumeLedger). Спрошено: добавлять ли число «сколько глав дописано сверх гранта», ведьdeliveredтеперь может превышатьmax_units. Цена вопроса названа: это класс «новое поле в опубликованном документе» — ратификация оркестратора плюс минорный бампStreamVersion, а промт запретил двигать контракт; платформа кадрVolumeсегодня не декодирует вовсе (platform/internal/ingest/events.go:Finished{Outcome}), потребителя у факта нет. РЕШЕНИЕ ВЛАДЕЛЬЦА: оставить как есть, поле не добавлять. Исполнено: поля нет, объяснение живёт словами в докстрингахDeliveredиFreeтого же кадра. - Семантика «юнит, начатый прогоном БЕЗ объёмного потолка, слота в следующей покупке не берёт; перенос ограничен размером гранта». Альтернативы названы: тратить на такие юниты купленное (тогда покупатель платит за главу дважды — ровно вред строки 232) либо завести схемный носитель «какая покупка оплатила какую строку». СЛОВО ВЛАДЕЛЬЦА: вынести оркестратору, решение отложено — «подумаем на этот счёт». ⇒ пункт остаётся ОТКРЫТЫМ вопросом к приёмке; в коде сейчас первый вариант, ограниченный грантом.
rebill_model_moved_rows— второе новое полеstatus --jsonсверх названного промтом одного; говорит, какая часть суммы завышена из-за смены модели стадии. Аддитивно, платформой игнорируется (её аллоулист не берёт ни одногоrebill_*); без него человекочитаемая строка и текст отказа перестают говорить дословно одно и то же. РЕШЕНИЕ ВЛАДЕЛЬЦА: оставить.- Ошибок в промте не нашла.
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 battery→MAKE_EXIT=0,golangci-lint0 issues,okв 18 пакетах, SKIP:TestMinerFullBookParity,TestHelperEventsRun,TestHelperKillLoop. Тесты^func Test:grep -rn '^func Test' backend --include=*_test.go | wc -l→ 1083 → 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-timeCarried. Это ВЫБОР, не необходимость, и он входит в тот же вопрос владельца.
Что НЕ удалось и что НЕ проверено (дофикс).
- Цикл из трёх покупок на флагнутом юните не замерен — см. Б10. Знаю, что не проверено; не чинил, потому что наряд прямо запретил трогать семантику переноса.
- Состояние
Delivered == Carriedс исходом классаunitFresh(Б3а) ни одной фикстурой не достигается; инвариант утверждён на сконструированном состоянии, и это сказано в самом тесте. - Живого прогона с платными вызовами не было ни в паке, ни в дофиксе.
- Оба остатка строки 232 (первая редакторская стадия; прерванная пере-делка) по-прежнему открыты и требуют схемного носителя.
- Четыре находки проверяющего названы, но НЕ чинятся — все четыре суть входы в отложенный владельцем вопрос о семантике переноса, и наряд прямо запретил её трогать:
- Клауза «finished OUTSIDE this grant» ключуется на
CarriedПОСЛЕreconcile, поэтому исчезает, когда все перенесённые юниты флагнулись: оператор видит «2 PAID FOR BUT FLAGGED», но не то, что обе оплаты шли вне гранта. Воспроизведено:VolumeStop{MaxUnits:2, Delivered:2, Carried:2}+ два флага классаunitCarried. - Перенесённый юнит с ПРОТУХШИМИ черновыми строками пере-покупает всю цепочку вне гранта, тогда как хелп флага обещает «дописать недостающее». Воспроизведено проверяющим:
granted()=0, два вызова провайдера на один юнит. - Подсказка в докстринге
Deliveredключуется наdelivered > max_unitsи молчит в форме «весь остаток перенесён», гдеdelivered == max_units(это же Б10 наряда). - Цикл из ТРЁХ последовательных покупок на флагнутом юните не гонял никто — ни приёмка, ни проверяющий, ни я.
- Клауза «finished OUTSIDE this grant» ключуется на
- Выживание трёх гарантий ФЧ-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).
⛔ ТРИ ВЕЩИ, КОТОРЫЕ ОРКЕСТРАТОРУ НАДО ЗНАТЬ ДЛЯ ЛЕНДИНГА:
- Наружу едет НЕ то число, что назвал промт, и это согласовано. §4(3) назвал
denied estimateи следующей фразой запретил его класс («цены вызовов не выходят»). Едет недостачаcommitted+reserved+estimate−ceiling, полеshortfall_micro_usd(строка 278 называлаnext_step_micro_usd). Две оговорки в доке поля: при непустом полёте это ВЕРХНЯЯ граница; дляday-скоупа поле ОПУЩЕНО (дневной потолок суммирует все книги стора, движковые цифры — одной). - Третье лечение пункта 1 («обрамление как ДАННЫХ») в ТЕКСТОВОЙ форме невыполнимо.
lang/data/injection.txtпобайтно входит вEmbeddedVersion()→cutTag→ внутрь каждогоunit.id: добавление одной строки пере-чеканило бы id всех книг. Сделано структурно. 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 живую улику с боевого прогона.
- (1)
-
📌 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.gostripHeading/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.yaml— 58 записей, из них 53status: approved, 16 с полемgender. В нём ровно те термины, на которых спотыкались вычитчики:资质 → талант(канон владельца D39.21),元石 → первобытный камень(а в пробе намайнилось 7 форм),甲等/乙等/丙等 → класс А/Б/В(а в переводе «категория C» ЛАТИНИЦЕЙ),蛊师 → гу-мастер. В~/books/gu-zhenren/probe-4axes/book.yamlключаglossary_seedНЕТ — 0 вхождений, и шапка стенда объявляет это сознательно: «Сид НЕ подключается — банк рождается майнером + банкнотой, как в холодном прогоне». ⇒ Прежняя формулировка «банк не подписан» (запись 02.09) НЕТОЧНА и настоящим уточняется: не подписан МАЙНЕНЫЙ банк, а подписанный канон просто НЕ ПОДКЛЮЧЁН. Весь измеренный дрейф (30 ключей из 102 с >1 передачей) — дрейф конвейера с отключённым каноном. Контр-факт на той же книге: с подписанным банком эффективная консистентность 99.3–100% (Д50.2, 375–548 пар). ⚠ Записи蛊в сиде НЕ ХВАТАЕТ поля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 (владелец). - Уже ПОСТРОЕНО: род
neuterend-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 — зона бэкенда, полигон в них не лезет; его законная часть — улики и замер (см. ниже).
- Уже в плане: вынести вердикт-поля из хеша = строка 49 (спека
-
⚠ ВХОД 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 опора покрывала 55–79%). Редакция 2 на склеенном по манифесту черновике (покрытие 99–100%) плюс активные нули (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, на уже купленном). Терминов с более чем одной передачей в тексте — 13–16% от измеренных; сменивших форму между главами — 6–8%. Независимым путём (поле
spread, считает сам движок): 30 записей из 102 несут >1 передачу, максимум 7 форм у одного ключа (元石: «юаньши · камень юань · изначальный камень · первородный камень…»). ⚠ Разброс МЕЖДУ режимами (0.3–1.9%) не превышает шум-пола (2.4%, снят по паре реплик одной руки) ⇒ дрейф на этом отрезке — свойство черновика и банка, не редактора; экономия на редакторе к нему отношения не имеет. -
⚠ Мои ошибки этого пака, названные вслух: первая редакция пре-рега имела невалидный первичный тест (ничьи в знаменателе против H₀=50% дают ошибку I рода 17.8%) и правило решения с непокрытым пространством исходов; гейт слепоты искал
[A-Za-z]{2,}и пропускал одиночные латинские буквы (23–25 на руку, слепота при этом не пробита — асимметрия 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, уlow0; обрывов по длине 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:72 ← llm/httpllm.go:415), только тела, без URL и заголовков — снято, что у low-рук в теле стоит reasoning_effort:"low", у ∅-рук ключа НЕТ, у glm-5 — thinking:{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.32–0.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давал книгу за $7–15, фаза — за $41–68. Оба верны — (а) «книга 1500 глав» в Д29.1 это 1500 НАШИХ единиц ≈ 735 глав Гу, (б) ресёрч считал ВИДИМЫЙ вывод, а уdeepseek-v4-pro46% токенов — размышление, и это ЧЕРНОВИК, а не проверка (96% предложений финала дословно есть в трейсе): модель пишет перевод дважды и обе копии тарифицируются по выходу. Правило для сметы: цену роли считать поtotal_tokens, а не по длине перевода. -
ЧТО ОСТАЛОСЬ И СКОЛЬКО СТОИТ (Д38.6, ранжировано): Шаг 7 — 15 глав Гу ПОДРЯД боевым профилем с ЗАСЕЯННЫМИ характер-листами, ~$2 + движковый прогон. Это единственный замер, дающий прибор под Вопрос 0 («консистентность на всю книгу»), и он же готовая in-loop телеметрия прода. ⛔ Без засева характер-листов результат ложно-отрицателен ПО ПОСТРОЕНИЮ: полей пола в банке нет вовсе, механизма не существовало ни в одном прогоне. Дальше — цензур-ось дешёвой линии $0.2–0.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, но по ИЮЛЬСКОМУ прайсу. Пере-счёт тех же клеток по текущему: связка $40–43 вместо $13–14. (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).
curlHTTP 200,guides/thinking_mode, 108 336 байт, sha256f28c4324…. Было (наша запись 10.08): две колонки, уdeepseek-v4-prolowмаппится вhigh, «рычаг бюджета размышления существует ТОЛЬКО у flash». Стало дословно: «identical fordeepseek-v4-flashanddeepseek-v4-pro», таблица одна,low → low; тумблер{"thinking":{"type":"disabled"}}подан как общий. ⇒ у якоря письма ПОЯВИЛСЯ рабочий рычаг размышления, которого не было при всех покупках фазы. ⚠ Это ДОКА, не поведенческая проба — по норме «слаг ≠ модель» перед деньгами нужна живая проба (единицы центов); сессия её НЕ делает без слова владельца. ⚠ Побочно с той же страницы, чего у нас не записано нигде: «Thinking mode does not support thetemperature… will have no effect» ⇒ нашtemperature: 0.3наdeepseek-v4-proмолча игнорируется. ⚠ И:effort:"low"у DeepSeek пере-вооружает эхо-мину — рычаг есть, бесплатным не будет. -
⭐⭐ ЧИСЛА ПО ЛУНЕ ПЕРЕ-СНЯТЫ ПОКЛЕТОЧНО ПО ЗАПРОСУ ВЛАДЕЛЬЦА (Д44.6), И ОНИ БОЛЬШЕ, ЧЕМ Я ПЕЧАТАЛ. Однопроходка, те же 16 английских глав, тот же промт,
finish=stop16/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.05–0.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_tokens3270, вызов с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.078–0.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.078–0.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.4–2.5, а рядом стоит рычаг ×7–11 — смена модели наgpt-5.6-luna(поглавно медиана ×7.1, по сумме ×11.4) — и он упирается НЕ в деньги, а в кап агент-сессий (нужно 16, свободно 14). Тратить доллары на ручку прежде, чем порядковый рычаг прочитан по КАЧЕСТВУ, — плохая экономика. ⚠ Операционное для чужих циклов: отказ гарда возвращает код 1, но в ФОНОВОМ shellset -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% связки) ⇒ читать «луну как черновик» значило бы потратить кап на шестипроцентный рычаг; читался порядковый (×7–11). Результат: средние местаZ02.33 ·ZF2.33 ·RN2.53 ·RL2.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:Z02.33 → 2.20 ·ZF2.33 → 2.53 ·RN2.53 → 2.60 ·RL2.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: 466–19 559), у луны 49% и ×3 (511–1 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»). Это опровергнуто пере-пином 13–15.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.2–4.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 (правки зонные, рукой не трогаю).
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.)