textmachine/docs/archive/reports/MINIRUN_REPORT_2026-07-25.md

78 KiB
Raw Permalink Blame History

Мини-прогон ~10 глав: сквозной тест построенного (гигиена → главный проход → проба банкноты → верификация)

Ревью-шапка оркестратора №8 (26.07, приёмка execute-first по СЫРЬЮ; ПРИНЯТ — D39.37). 0 блокеров. Ре-ранено: build/vet/gofmt · -race 13/13 · ценз ИМЁН 475→492 (удалено 0) · парити EXACT · маскированный дифф golden против HEAD пуст вне трёх заявленных осей. Деньги сверены по сырым леджерам до цента: $0.114291 (проекция = списание ТОЧНО) + $0.021688 + $0.003081 (обе оплаты в spend) + $0.048855 + $0.046668 брака = $0.234583. Спот-чеки: банкнота 71/9из20/0 по БД · v11 реальна · banknote_detail несёт «学堂家老 → старейшина школы» · RegressionGuard live-срабатывание подтверждено МОИМ ре-раном (number_drift:[66]). Находка рубежа-2: моя мутация «отключить джойн WHAT в колл-сайте» ВЫЖИЛА по всей сьюте — фикс доказан прогоном, но не запинён тестом; фикс-лист №1 следующего касания. Оговорки хендоффа §2 ратифицированы как норма чтения этих чисел; хвосты §5 — в трекере с диспозициями (D39.37).

Сессия: бэкенд, одна сессия делает всё (решение владельца). Промт — docs/archive/prompts/BACKEND_MINIRUN_SESSION_PROMPT.md. Дата: 2026-07-25. Книга: 蛊真人, главы 110, новый проект guzhenren-minirun (вне git).

⟶ ЧИТАТЬ ВМЕСТЕ С ХЕНДОФФОМ MINIRUN_HANDOFF_2026-07-26.md. Там — вес каждого числа этого отчёта (что оно доказывает и чего НЕ доказывает), самооценка честности фиксов, методические ошибки сессии и 8 хвостов, увиденных но не чиненных. Отдельные выводы §6.2 хендофф уточняет: срабатывание dc2 — не дефект реализации, а принятая неоднозначность класса.


§0. ПРЕ-РЕГИСТРАЦИЯ (написана ДО первой траты; ниже НЕ переписывается)

Это первый раздел отчёта и он зафиксирован до единого платного вызова. Причина названа в промте прямо: принцип author ≠ reviewer снят, а по переписи инцидентов проекта самоотчёт — доминирующий канал ошибок (62 из 180). Прогон, у которого критерий успеха дописан после результата, ничего не доказывает, поэтому критерий провала назван здесь заранее.

0.1 Что меряем (M1M8)

# Утверждение, которое прогон обязан подтвердить СЫРЬЁМ Артефакт-носитель
M1 Гейт согласия на пере-оплату (пак-18) отработал ЖИВЬЁМ: показал проекцию (N единиц, ~$X), отказал без флага ДО первой резервации, прошёл с флагом лог отказа, chunk_status, SpentUSD до/после
M2 Майнинг-стоп остановил прогон перед волной редактуры, записал подписную карту, очистился после подписи (промоушен + reject) *.db.mined-signature.yaml, mined-delta.yaml, mined-rejects.yaml, логи
M3 Чекеры и QualityReport дали ОСТАТОК ДЕФЕКТОВ по классам ($0 read-only скан) — главное измерение прогона tmctl report, repair_candidates
M4 RegressionGuard ПОСЛЕ флипа даёт наблюдаемость (длина/числовой дрейф видны) retrieval_state.n_style_flags + style_detail
M5 Лейбл-путь = no-op: резолвнутые модели тождественны конфиговым, ноль строк проблем маршрутизации tmctl report/status --json, chunk_status.model_*
M6 Деньги durable: доля finish=stop, эхо-класс, reserve→settle одной транзакцией, итог против потолка и против оценки request_log, checkpoints, ledger
M7 escalation_model держит ОТВЕТИВШУЮ модель, а не попробованную chunk_status.escalation_model
M8 Канал WHAT (банкнота) физически работает от промпта до парсера сырые тела ответов (LOG_LLM_BODIES), retrieval_state банкнота-телеметрия

0.2 Пороги и ожидания (названы заранее)

  • Деньги главного прохода: ожидание $0.100.19 (драфт ≈$0.022 + редактура ≈$0.080.15; экстраполяция фактических цифр rerun2 на срез ровно вдвое больший). Потолки книги/дня — $1.00/$1.00, выставлены с 56× запасом, но конечны: гейт потолка обязан быть способен выстрелить.
  • Проба банкноты: ожидание ≈$0.02 (только волна черновика).
  • Проба гейта пере-оплаты (пас-лег): ожидание ≤$0.01 (отдельный микро-проект в одну главу, чтобы «проход с флагом» стоил центы, а не второй прогон).
  • Судья НЕ вызывается. Петля ремонта остаётся enabled: false. Второй арм (glm-5) НЕ гоняется без отдельного слова владельца.

0.3 ЧТО МЫ ЗАРАНЕЕ НАЗЫВАЕМ ПРОВАЛОМ

# Провал (заранее)
П1 Фактическая стоимость главного прохода > $0.40 (вдвое выше верха оценки) — модель денег неверна
П2 Пробит потолок книги/дня ИЛИ committed ≠ SUM(checkpoints) вне ратифицированного исключения redrive
П3 Эхо-класс (cjk_artifact) на черновике > 0 — эхо-мина DeepSeek жива при thinking-ON
П4 Гейт пере-оплаты НЕ отказал при проекции выше порога, ИЛИ отказал ПОСЛЕ резервации денег (сырьё: любая новая строка ledger/checkpoint на отказе)
П5 Майнинг-стоп НЕ остановил прогон при непустой дельте, ИЛИ не очистился после того, как каждый терм промоутнут/отклонён
П6 RegressionGuard после флипа молчит, а ручная проверка находит реальный обвал длины/числовой дрейф в отгруженном тексте. (Честный ноль при отсутствии дрейфа — НЕ провал.)
П7 Хоть одна резолвнутая модель ≠ конфиговой ИЛИ есть хоть одна строка проблем маршрутизации на книге без лейблов
П8 Банкнота: n_banknote_lines = 0 по ВСЕМ чанкам (модель не выдаёт блок) ИЛИ parse_fail > 0 (парсер не принимает то, что модель выдаёт)
П9 Остаток дефектов отчитан СЫРЫМ счётчиком без ручного отделения ложняков — решение владельца о платной петле принимается по ЧИСТОМУ остатку
П10 Потеря/порча данных: битая БД, рваное состояние после прерывания, утрата фактуры rerun2

0.4 Что заранее объявлено НЕ провалом (чтобы задним числом не переписать)

  • Майнинг-стоп с нулём кандидатов — законный исход (сид уже покрывает главы 110). Тогда M2 остаётся НЕДОКАЗАННЫМ и отчитывается именно так, а не как успех.
  • Эскалация не случилась — законный исход; M7 остаётся НЕДОКАЗАННЫМ.
  • Термины приходят на подпись БЕЗ dst — это сегодняшнее ОЖИДАЕМОЕ поведение (D39.36), фиксируется как факт, а не как авария.
  • Разрыв канона 元-семейства (元海/真元/元石 расщеплены, единый корень ждёт владельца), отсутствие 学堂家老 в сиде, 赤城 только внутри 古月赤城 — ИЗВЕСТНЫЕ разрывы, объявленные ДО прогона; чтение результата не имеет права приписывать их качеству перевода.
  • Качество перевода как таковое НЕ измеряется (судья не зовётся); прогон отвечает на вопрос «работают ли узлы», а не «хорош ли текст».

0.5 Пре-регистрационные факты стенда (зафиксированы до трат)

  • Бэкап rerun2/*.db сделан ДО первой write-команды: /home/ubuntu/books/gu-zhenren/backup-pre-minirun-2026-07-25/ (3 БД + shm/wal).
  • Срез: строки 93837 исходного guzhenren-gb18030.txt = 10 глав, 57 838 байт GB18030. Метод среза проверен воспроизведением: строки 93469 дают файл, байт-в-байт равный rerun2/guzhenren-ch1-5.gb18030.txt (sha256 8755afd3…d3d76f64).
  • Манифест до прогона: 10 глав, 14 edit-единиц (tmctl status, $0).
  • Слаги живьём (правило двух направлений, до платных вызовов): GET /v1/models DeepSeek → ['deepseek-v4-flash', 'deepseek-v4-pro'], оба слага конфига живы. prices_checked: 2026-07-10 (15 дней, порог 120).
  • Ре-чек ToS (D39.32 п.4): проверено, изменений нет. Триггеры не наступили: головной Google ToS — 30.07.2026 (впереди), правок accepts_labels в этой сессии не было, книга лейблов не несёт, Gemini в цепочке этого прогона не участвует.

§1. ШАГ 0 — ГИГИЕНА (исполнена ДО прогона, $0-код)

1.1 Обязательный флип Gates.RegressionGuard.Enabled (D38.4 п.5, невыполненное обязательство D39.34)

Включён во всех пяти шиппинг-конфигах: pipeline-c1.yaml · pipeline-c2.yaml · pipeline-arm-deepseek-pro.yaml · pipeline-arm-glm.yaml · pipeline-arm-mistral.yaml (grep -c regression_guard configs/*.yaml = 5). C2 включён осознанно: у него ЕСТЬ стадия edit, значит переход черновик→финал существует и гард не вырожден.

Флип НЕ двигает снапшот — проверено исполнением, а не рассуждением: в логах одного и того же прогона с гейтом и без него обе волны рендерят те же id (snapshot=2ab1b7578d40 драфт, 46e9bc2bcf5a эдит). Пороги гарда — код-консты, а его версия уже сидит в CheapGateVersionпере-оплаты флип не стоит.

Покрыт тестом, что гейт РЕАЛЬНО стреляетinternal/pipeline/regressionguard_live_test.go, три теста через настоящий драйвер (норма 11):

  • TestRegressionGuardFiresLiveWhenEnabled — редактор возвращает текст вчетверо короче черновика и без двух многозначных чисел ⇒ n_style_flags=3, в style_detail "length_collapse":1, "number_drift":2 и сами человекочитаемые строки;
  • TestRegressionGuardSilentWhenDisabled — тот же прогон без гейта ⇒ 0 (гейт opt-in, «выключён = байт-идентично»);
  • TestRegressionGuardComparesDraftAgainstFinal — редактор возвращает черновик БЕЗ изменений ⇒ 0. Пинит, ЧТО именно волна подаёт гарду: разводка «финал против финала» (законная форма драфт-волны) отчитывалась бы чистой книгой вечно.

1.2 Два нита общности (условность снята D39.35)

нит было стало
множитель DC1 expectedHours := n * 2 в internal/checks/checkers.go n * c.dc1UnitHours, значение из dc_ratio dc1_unit_in_hours 2 в configs/langpacks/zh-ru/dc-checkers.txt
Detail-строки Go-литералы с 时辰/千万/数十万/成 в generic-файле шаблоны msg<TAB>key<TAB>template в пар-паке, подстановка {name}

Форма выбрана fail-loud, без Go-дефолта: пак, который несёт детекцию, но не несёт шаблон/отношение, — корраптный, и CompileCheckers падает так же, как на битом регексе (mustPairRatio/mustPairMessages). Это снимает возражение D39.31 п.5 («дефолт шаблона обязан рендерить текущую строку, значит 时辰-литерал остаётся в Go») — дефолта просто нет.

Заодно из engine-файлов убраны ЦЕЛЕВЫЕ литералы, которые соврали бы второй паре/второму таргету, без всякой новой данных-механики: «万/億» и пример 三万→«три миллиона» из сообщения магнитудного гейта, «no valid Russian word» → «the target has no well-formed word», «Latin word … in the Russian output» → «in the target output».

Тесты (internal/checks/checkers_pairdata_test.go): синтетический «второй пар-пак» с отношением 1:1 МОЛЧИТ там, где 2:1 флагает (TestDC1UnitRatioIsPairData); каждая пар-строка рендерится из пакета, а не из Go (TestCheckerDetailTextComesFromPairData); корраптный пак падает с именем недостающего ключа (TestCorruptPairPackFailsLoud, 4 кейса); книга без пакета остаётся инертной (TestNoPackStaysInert).

Сдвинутая версионная ось — ровно одна, называю строкой (как требует промт): langpack_version langpack-v2-a7d4be2c0465langpack-v2-a28ed743c99c (замер: тот же пробный тест на HEAD-дереве и на рабочем). Двигает ОБА волновых снапшота для книг, ссылающихся на репозиторный каталог langpack. Для мини-прогона это бесплатно (новый проект), для стендовых книг rerun2 — часть уже состоявшегося расхождения D39.35. CheapGateVersion НЕ бампался осознанно: изменились ТЕКСТЫ строк, а не счётчики и не вердикты; пар-сообщения теперь данные, и их версия — это и есть хеш пакета.

1.3 Опциональное: проекция пере-оплаты в tmctl status (спека D15.2 §9)

Добавлены rebill_units/rebill_usd (оба omitempty) + строка в человекочитаемом рендере. Считает тот же projectRebill, на котором отказывает гейт, — одно определение числа, а не второе, дрейфующее. Булев ConfigDrift СОХРАНЁН (не заменён): его читает полигонная экстракция, а добавление чисел аддитивно. Тест TestStatusPricesTheDriftWithTheGatesOwnNumber пинит, что цифра статуса равна и фактически списанному, и той, что называет отказ гейта.

1.4 Приёмка гигиены исполнением

проверка результат
go build ./... && go vet ./... чисто
go test ./... -race 15 пакетов ok, 0 FAIL
golden 211c9013f5cfa31562857cc9518488393a647cce489d37113402b159089045d6байт-в-байт равен HEAD (git show HEAD:…| sha256sum), пере-капчера не было
ценз диффом ИМЁН тестов 475 → 483, удалено 0 (8 добавленных перечислены выше)
мутации (самопроверка исполнением) 5 мутаций — 5 красных: RegressionEnabled:false · RunCheapGates(…, finalText, finalText, …) · n * 2 вместо данных · renderMsg без подстановки · status не пишет проекцию

§2. ГЛАВНЫЙ ПРОХОД — что произошло

манифест 10 глав → 20 драфт-чанков14 edit-единиц
прогон 1 драфт-волна целиком, STOP на майнинг-стопе (exit 3), $0.022205
подпись, раунд 1 学堂 → «школа» (владелец рассмотрел «академия», подписал «школа»)
прогон 2 драфт резюмнулся за $0.00, стоп СНОВА (exit 3) — расчехлился 学堂家老
подпись, раунд 2 学堂家老 → «старейшина школы»
прогон 3 «bank-mining: empty delta, auto-continuing», edit-волна 14/14 ok, $0.092086
итог 14/14 units done, 0 flagged, committed $0.114291, потолок $1.00 (11.4%)

Эскалация случилась одна: ch3/chunk0 драфт flagged cjk_artifact → хоп deepseek-v4-pro → ok. Два edit-юнита (ch5/0, ch6/0) упёрлись в max_tokens=8000, ретрай на 16000 вытащил оба.


§3. ПРОБА БАНКНОТЫ (отдельный проект, только волна черновика)

Проект minirun-banknote/: своя БД, свой book.yaml, КОПИЯ промпта переводчика с блоком ⟦TM-BANK-v1⟧ (шиппинг-файл не тронут), gates.banknote.enabled: true, LOG_LLM_BODIES=1 LOG_LEVEL=debug. $0.021688, 20/20 чанков ok.

метрика значение
n_banknote_lines (сумма) 71 строка на 9 из 20 чанков
banknote_parse_fail 1 чанк (ch3/chunk0)
banknote_truncated 0
производных чекпоинтов banknote_export 9
сепаратор в чистом экспорте 0 вхождений (grep -c по export-banknote.txt), табличных строк-остатков — 0

§4. ПРОБА ГЕЙТА СОГЛАСИЯ НА ПЕРЕ-ОПЛАТУ

Гейт стрелял живьём дважды: на микро-проекте minirun-rebill/ (одна глава, чтобы «проход с флагом» стоил центы) и на ГЛАВНОМ проекте (только отказ — он бесплатен).

лег команда исход
проекция status ⚠ RE-PAYMENT: 2 chunk×stage unit(s) … ~$0.001629
отказ без флага translate exit 1, «NOTHING was reserved and no row was touched»
отказ на --resnapshot БЕЗ согласия translate --resnapshot exit 1 — ре-пин ≠ согласие на КОНКРЕТНУЮ сумму (развилка пака-18 подтверждена живьём)
отказ по потолку --accept-rebill=0.0001 exit 1: «caps consent at $0.000100 — refusing»
проход с флагом --resnapshot --accept-rebill WARN rebill_units=2 rebill_usd=0.001629 threshold_usd=0.000081, прогон пере-оплатил $0.001452
главный проект (обе волны сдвинуты) status + translate 34 chunk×stage unit(s) … ~$0.114291, отказ; порог $0.005715 (5% от $0.114291)

Деньги ДО и ПОСЛЕ трёх отказов побайтно те же: spend $0.0016289784 → $0.0016289784, checkpoints 2 → 2, request_log 2 → 2, snapshot_id в chunk_status не сдвинулся. Отказ происходит до резервации и до провайдерского вызова, а не после.

После возврата конфига в исходное состояние снапшот вернулся (2299964c3e56) и проекция замолчала — то есть отказ не оставил следа, а гейт есть чистая функция конфига.


§5. ВЕРДИКТЫ ПО ШАГУ 4 (каждый — с артефактом; проверял так, будто отчёт писал не я)

4.1 Гейт согласия на пере-оплату — ПОДТВЕРЖДЁН ЖИВЬЁМ (первое исполнение механизма)

Фактура — §4. Отказ ДО денег доказан сырьём, а не текстом сообщения: spend/checkpoints/request_log/snapshot_id побайтно те же после трёх отказов. Сверка проекции с фактической тратой: проекция главного проекта 34 единицы, ~$0.114291 точно равна spend.committed_usd = $0.11429117. Расхождение отсутствует, потому что проекция суммирует хранимые chunk_status.cost_usd — то есть буквально то, что уже было списано. На микро-проекте проекция $0.001629, а фактическая пере-оплата $0.001452 (11%): это не ошибка проекции, а её семантика — она отвечает «сколько стоила эта работа В ПЕРВЫЙ РАЗ», а второй раз провайдер отдал часть промпта из кэша. Направление безопасное (перед фактом называется не-заниженное число).

4.2 Майнинг-стоп — ПОДТВЕРЖДЁН, с новым фактом о его форме

Остановился перед edit-волной (exit 3, WARN terms=1), записал подписную карту, после подписи дельта опустела («empty delta, auto-continuing to the edit wave») и стоп не повторился. Драфт-волна при этом резюмнулась за $0.00request_log 40 строк tm_hit=1, cost 0) — «пере-оплачено ОДИН раз» держится.

Термы приходят БЕЗ dst — подтверждено, как ожидаемое поведение (D39.36), не как авария: в обеих подписных картах dst: "".

НОВОЕ (не предсказано ни промтом, ни D39.36): стоп очищается РАУНДАМИ, а не одним заходом. Промоушен 学堂 расчехлил 学堂家老, которого в первом раунде в карте не было (его перекрывала эмиссия). Владелец на первом стопе видит «1 терм» и не может знать, что подписей будет 2 (а на книге — неизвестно сколько). Это не дефект кода, но это свойство контракта, которое стоит назвать вслух рядом с «опциональным ОК» из D39.36.

4.3 Банк памяти — ПОДТВЕРЖДЁН, с независимой сверкой глазами

injections(exact)=268 · sticky=64 · ambiguous=5 · spoiler-blocked=0 · evicted=0 · post-check-misses=9 на 20 чанках (ориентир прошлого прогона — 107/3 на 10 чанков; здесь вдвое больше чанков и вдвое больше попаданий).

Независимая проверка (взял термины из глоссария, нашёл в исходнике, посмотрел финальный текст):

терм (канон) что в отгруженном тексте вердикт
蛊虫 «гу-червь» ×3 «гу-червей», «гу-червям» перевод ВЕРЕН; в decl.forms сида только ЕДИНСТВЕННОЕ число ⇒ промах записан честно, но это дыра в данных сида, не дефект перевода
月兰花 «лунная орхидея» «лунных орхидей» то же — множественного числа в формах нет
甲等/丙等 «класс А»/«класс В» «талантом класса «А»», «класса «В»» смысл верен, канон-форма не воспроизведена буквально: редактор добавил кавычки вокруг литеры
开窍 «открытие апертуры» ×2 «Церемония открытия апертур» форма-дрейф (мн. ч. «апертур» вместо «апертуры»)
族长 «глава клана» «Первый глава рода», «в нашем роду Гуюэ» РЕАЛЬНЫЙ ДРЕЙФ КАНОНА — ровно тот, о котором предупреждает заметка самого сида («⚠ консистентность род/клан»)

Итого 9 промахов: 1 реальный дрейф канона · 4 формальных/косметических · 4 — отсутствие мн. ч. в сиде.

4.4 Чекеры и остаток дефектов — ГЛАВНОЕ ИЗМЕРЕНИЕ ⚠ см. §6

4.5 RegressionGuard после включения — ЧЕСТНЫЙ НОЛЬ (проверен независимо)

Гард зафиксировал 0 обвалов длины и 0 числовых дрейфов. Пре-регистрация требовала не поверить этому нулю на слово (П6), поэтому я пересчитал переход черновик→финал сам, по чекпоинтам и экспорту:

  • отношение непробельных символов финал/черновик по 14 единицам: 0.90 … 1.06 (порог гарда — падение ниже 0.60);
  • многозначных чисел ПОТЕРЯНО: 0 во всех 14 единицах;
  • единственное «появившееся» число — 10 в ch10/0, и это артефакт МОЕЙ сверки: ApplyHeading дописывает «Глава 10» в экспорт ПОСЛЕ того, как гейты отработали (у глав 19 номера однозначные и правилом «≥2 цифр» отсекаются).

⇒ ноль гарда — правда, а не молчание. Наблюдаемость при этом работает: соседние классы в том же канале дали 11 флагов с деталями.

4.6 Путь content-лейблов = no-op — ПОДТВЕРЖДЁН

SELECT count(*) FROM checkpoints WHERE model_requested <> model_actual = 0. Резолвнутые модели тождественны конфиговым: draft/deepseek-v4-flash ×20, draft/deepseek-v4-pro ×1 (это сконфигурированный escalate_to), edit/deepseek-v4-pro ×16. В status --json полей маршрутизации/лейблов НЕТ ВООБЩЕ (все omitempty) ⇒ read-model книги без лейблов байт-идентичен до-паковому, строк проблем маршрутизации ноль.

4.7 Деньги durable — ПОДТВЕРЖДЁН (по строкам БД)

проверка значение
spend.committed_usd 0.11429117
SUM(checkpoints.cost_usd) 0.11429117 (37 строк)
SUM(chunk_status.cost_usd) 0.11429117
reserved в покое 0.0
jobs 20/20 done
доля finish=stop 35/37 = 94.6% (2 × length, оба вытащены ретраем)
потолок $0.114291 из $1.00 = 11.4%

Инвариант committed == SUM(checkpoints) держится ТОЧНО, резервов в покое нет ⇒ на этом прогоне не осталось ни одной незакрытой резервации. Честная оговорка о границе доказательства: «reserve→settle одной транзакцией» этот прогон подтверждает КОСВЕННО (нет рваных состояний после 6 запусков процесса); прямое доказательство атомарности — kill9_test.go в CI, живого kill -9 в этом прогоне не делалось.

Эхо-класс — см. §7-Д1: сырой факт «1 эхо из 20», отчётная метрика — 0.0%.

4.8 Слаги и цены живые —

GET /v1/models DeepSeek до платных вызовов: ['deepseek-v4-flash','deepseek-v4-pro']оба слага конфига живы, катовер deepseek-chat (24.07) нас не касается. prices_checked: 2026-07-10 (15 дней при пороге 120). Ре-чек ToS (D39.32): проверено, изменений нет (триггеры не наступили).

4.9 Канал WHAT — ФИЗИЧЕСКИ РАБОТАЕТ, с двумя поправками к тому, как его смотреть

  • n_banknote_lines = 71 > 0 ✔ · truncated = 0 ✔ · сепаратор в чистом черновике отсутствует (срезался) ✔ · parse_fail = 1 ✘ (диагноз ниже).
  • Диагноз единственного parse_fail: модель выдала строку Бам, бам-бам → Тук, тук-тук — звукоподражание, в src НЕТ ни одного ханьца. Парсер отверг её по правилу hasBankSrcHan — то есть отработал КАК ЗАДУМАН, а негодную строку произвела модель. Флаг сделал свою работу; чинить парсер не надо.

Оценка предложений ГЛАЗАМИ (выборка — все 71 строка, ниже 15 характерных):

Годятся как основа канона: 力量蛊 «гу Силы» · 智慧蛊 «гу Мудрости» (обе — дословно то, что владелец подписал в rerun2 своими руками) · 古月方源 «Гуюэ Фан Юань» · 古月陈博 «Гуюэ Чэньбо» (совпало с подписью rerun2) · 沈嬷嬷 «матушка Шэнь» · 开窍大典 «Церемония открытия апертуры» (дважды одинаково) · 紫府 «Пурпурный дворец» · 华池 «Нефритовый пруд» · 青铜海 «Бронзовое море» · 元石碎块 «осколок первобытного камня» (согласовано с сидовым 元石) · 学堂家老 (три варианта — и это ПОЛЕЗНЫЙ сигнал: терм дрейфует, нужен канон; именно его владелец сегодня и подписал).

Шум, который пришлось бы отклонять: 少年/中年/老年 «юность/средний возраст/старость» · 无 «нет» · 十二分之一 «одна двенадцатая» · 雨声 «звук дождя» · 停息 «прекратиться» · строка-звукоподражание без ханьца.

Прямой ответ на вопрос промта: предложения годятся как основа канона, но не как автоматический канон. Полезная доля — примерно 4045% строк (имена, титулы, гу-термины, топонимы); остальное — обиходная лексика и числовые выражения, которые владелец отклонял бы. Ценность в том, что предложение приходит ВМЕСТЕ с исходником, а альтернатива сегодня — придумывать русский вариант с нуля на голом терме. Починка шва работы стоит.


§6. ГЛАВНОЕ ИЗМЕРЕНИЕ: ОСТАТОК ДЕФЕКТОВ, ЛОЖНЯКИ ОТДЕЛЕНЫ

Read-only скан ($0) по отгруженному тексту 10 глав.

6.1 Остаток в классах, которые петля ремонта УМЕЕТ чинить

repair_candidates = 0. По классам — пусто: DC1 время 0 · латиница-остаток 0 · битая словоформа 0. (Строка в рендере печатается только при >0; проверено по коду render.go:277 и по --json-полю repair_candidates,omitempty.)

Вход в решение владельца о включении платной петли (D39.24): на этих 10 главах петля не нашла бы НИ ОДНОЙ работы. Она бы отработала вхолостую и стоила бы только денег на скан. Это аргумент НЕ включать её сейчас — но аргумент слабый по объёму выборки: 14 единиц, один арм, одна книга.

6.2 Сырой счётчик наблюдаемости — 11 флагов. Каждый разобран ГЛАЗАМИ

класс сырых реальных ложняков почему
dialogue_dash (смешение стилей речи) 8 0 8 «…»-строки — это ВНУТРЕННИЙ МОНОЛОГ («Становится всё интереснее», — усмехнулся про себя Фан Юань), а «—» — звучащая речь. Это НОРМА русской типографики, а не смешение стилей. Чекер бьёт по законному приёму
percent_scale (成 как дробь) 2 0 2 «три десятых» = 30%, «сорок четыре сотых» = 44% — масштаб верен, отличается только ФОРМА. Заявленный класс («~100× ошибка масштаба») не реализовался
dc2_magnitude (千万 как «тысячи») 1 0 1 杀了千万人 — стоковая ГИПЕРБОЛА («погубил тысячи и тысячи людей»), о чём предупреждает комментарий самого чекера (§5-A4)
ИТОГО 11 0 11

6.3 Остаток по каналу памяти (пост-чек)

9 подтверждённых промахов → после разбора глазами: 1 реальный дрейф канона (族长 «глава рода» вместо «глава клана») · 4 формальных (кавычки вокруг литеры класса ×2, «апертур» вместо «апертуры» ×2) · 4 — дыра в данных сида (нет форм мн. ч. у 蛊虫 и 月兰花).

6.4 ЧИСТЫЙ ОСТАТОК — то, по чему принимается решение

адресуемых петлёй ремонта дефектов 0
реальных дефектов, найденных детерминированными чекерами 0 из 11 сигналов (все 11 — ложняки)
реальных дефектов канона, найденных банком 1 (族长 → род/клан)
дефектов, вызванных дырой в ДАННЫХ, а не кодом 4 (мн. ч. в decl.forms сида)
структурный KPI 3.20 предложения на нарративный абзац (обвала в «одно предложение — абзац» нет)
эхо / косметический стрип / вырожденные циклы 0 / 0 / 0

Честный вывод: на этой выборке платить за петлю ремонта не за что, а деньги, которые стоило бы потратить, лежат в двух других местах — в чистке ЛОЖНЯКОВ чекеров (иначе цифра «11 флагов» будет вводить в заблуждение на каждом прогоне) и в ДАННЫХ сида (формы мн. ч.). Обе работы $0.


§7. ДЕНЬГИ: ФАКТ ПРОТИВ ОЦЕНКИ

статья оценка промта факт вердикт
главный проход (один арм) $0.100.19 $0.114291 попал в вилку
— драфт ≈$0.022 $0.022205 попал почти точно
— редактура $0.080.15 $0.092086 попал
проба банкноты ≈$0.02 $0.021688 попал
проба гейта пере-оплаты ≤$0.01 (моя пре-рег) $0.003081 попал
ВСЕГО за сессию $0.139060

Где оценка промта оказалась неточна (прямой ответ на вопрос «скажи, где я ошибся»): нигде по сумме — но вилка была построена как «удвоенный rerun2» и случайно совпала, погасив внутри себя 16% брака. Из $0.114291 главного прохода $0.018337 ушло в ПРОВАЛЬНЫЕ попытки: $0.000638 — эхо-черновик, $0.017699 — две обрезанные по max_tokens попытки редактора (см. §8-Д2). Без этого брака проход стоил бы ≈$0.096. То есть модель «драфт + редактура» верна, а вот статьи «брак» в ней нет вообще, и на этом прогоне она составила шестую часть счёта.


§8. НАЙДЕННЫЕ ДЕФЕКТЫ (то, ради чего прогон и затевался)

Д1 — MEDIUM, наблюдаемость: эхо, вылеченное эскалацией, отчитывается как «эха не было»

Сырьё: request_log 18:53:02 — ch3/chunk0 draft, ok=0, err=cjk_artifact, $0.000638. chunk_status той же строки: disposition=ok, escalated=1, escalation_model=deepseek-v4-pro. tmctl report: echo draft=0 (0.0%).

Корень (internal/pipeline/quality.go:245): draftEcho считает строки, у которых chunk_status.flag_reason == cjk_artifact. Успешная эскалация переписывает строку в ok с пустым flag_reason ⇒ эхо исчезает из метрики. Доккоммент честно перечисляет случай c-lite (упавший мембер), но случай «эскалация вылечила» в него не попал.

Почему это важно: эхо-рейт — единственный числовой сторож эхо-мины DeepSeek (D18/D19), и он показывает 0.0% там, где живьём было 5% (1 из 20). На книге в 2284 раздела так теряется весь класс.

Предлагаемый фикс (в пак-19 или отдельной мелочью): считать echo_draft по request_log (attempt-уровень, err=cjk_artifact), а не по финальной строке chunk_status; либо завести на chunk_status durable-флаг «первичная попытка эхнула». Первое дешевле и не трогает схему.

Д2 — MEDIUM, деньги: редактор упирается в max_tokens = флор модели, и это 15.5% счёта

Сырьё: ch5/0 (finish=length, классифицировано empty, $0.008706) и ch6/0 (finish=length, $0.008993) — оба на max_tokens=8000; WARN «stage flagged, regenerating with a larger budget … next_max_tokens=16000»; вторые попытки прошли (ch6/0 отдал 10 951 completion-токен).

Корень: у deepseek-v4-pro capabilities.min_max_tokens: 8000 (флор из D24.3, калиброванный под ЧЕРНОВИК), а max_output_ratio: 2.2 на edit-единице в 3200 ru-токенов даёт меньше флора ⇒ бюджет ВСЕГДА ровно 8000. При этом у DeepSeek thinking-токены входят в completion (reasoning: subset), то есть 8000 делятся между размышлением и текстом. Крупная единица не помещается — платим дважды.

Предлагаемый фикс: считать потолок редактора от РАЗМЕРА ЧЕРНОВИКА единицы (вход редактора), а не от исходника, и/или поднять флор редакторской роли. Дешёвая мера до дизайна — поднять min_max_tokens в конфиге арма. Не делал: это правка поведения вне скоупа промта, и она двигает снапшот.

Д3 — LOW, инструментальный: LOG_LLM_BODIES обрезает тела на 4096 БАЙТ — банкноту в логах не увидеть

internal/obs/logging.go:88: llmBodyLogMax = 4096. Кириллица — 2 байта на символ, перевод чанка — 48 КБ, а блок банкноты идёт В КОНЦЕ ответа ⇒ он гарантированно за отсечкой. Способ, предписанный промтом («единственный способ увидеть сами предложения — сырые тела»), физически не работает.

Д4 — ПОПРАВКА К D39.36 (хорошая новость, меняет цену починки шва)

D39.36 утверждает: «предложенный перевод не остаётся и в артефактах прогона». Это не так. Проверено: SELECT count(*) FROM checkpoints WHERE response_text LIKE '%⟦TM-BANK-v1⟧%' = 9 — первичный чекпоинт попытки хранит СЫРОЙ текст ответа вместе с блоком; чистится только ПРОИЗВОДНЫЙ чекпоинт banknote_export (9 строк, во всех блока нет), который и читают редактор с экспортом.

⇒ выбрасывается не текст, а распарсенная структура (_, flags = parseBanknote(...), banknote.go:177). Практическое следствие: чинить шов можно, не пере-прогоняя ничего — dst за любой уже сделанный прогон с включённым каналом восстановим из БД. Именно так я и достал 71 строку для оценки в §5-4.9.

Д5 — свойство контракта (не баг): майнинг-стоп очищается РАУНДАМИ

Подпись 学堂 расчехлила 学堂家老 (второй стоп, второй заход владельца). На книге число раундов заранее неизвестно. Ложится прямо в развилку D39.36 («опциональный ОК вместо жёсткого стопа») как дополнительный аргумент: сегодня цена стопа — не одна пауза, а неизвестное их число.

Д6 — данные, не код: в сиде нет форм МНОЖЕСТВЕННОГО числа

4 из 9 промахов пост-чека — «гу-червей», «гу-червям», «лунных орхидей»: перевод верен, а decl.forms перечисляет только единственное число. Дешёвая правка данных, которая уберёт треть шума пост-чека. Не делал: сид — зона владельца.

Д7 — качество чекеров: 11 сигналов из 11 — ложные (см. §6.2)

Самый крупный класс (dialogue_dash, 8 из 11) systematically бьёт по ЗАКОННОЙ русской типографике «мысль в «…» против речи в «—»». Пока это не исправлено, книжная цифра «N стилевых флагов» не является входом ни в какое решение.


§9. ПРЕ-РЕГИСТРАЦИОННЫЕ КРИТЕРИИ: ЧТО СРАБОТАЛО

Критерии из §0.3 применяю дословно, БЕЗ переопределения задним числом.

# статус по факту
П1 стоимость > $0.40 не сработал $0.114291
П2 потолок / committed ≠ SUM(checkpoints) не сработал равенство точное, потолок 11.4%
П3 эхо-класс на черновике > 0 СРАБОТАЛ 1 из 20 драфт-чанков (5%) отдал cjk_artifact при thinking-ON
П4 гейт не отказал / отказал после резервации не сработал отказал трижды, ничего не тронув
П5 стоп не остановил / не очистился не сработал остановился и очистился (за два раунда)
П6 гард молчит при реальном дрейфе не сработал ноль перепроверен независимо: дрейфа нет
П7 модель ≠ конфиговой / строки маршрутизации не сработал 0 расхождений, 0 строк
П8 parse_fail > 0 СРАБОТАЛ 1 чанк — строка без ханьца в src
П9 остаток без отделения ложняков не сработал ложняки отделены поимённо (§6.2)
П10 потеря/порча данных не сработал бэкап цел, БД мигрировала v9→v10 штатно, рваных состояний нет

Разбор двух сработавших — без смягчения формулировки:

  • П3 сработал, и я не переопределяю его задним числом. Эхо DeepSeek живо при thinking-ON: 5% на этом срезе (D18 мерил 25% на приёмочной книге — порядок тот же). Механизм ответа отработал ровно как ратифицирован: класс распознан, single-hop эскалация на deepseek-v4-pro вылечила чанк, книга не пострадала. Но факт остаётся фактом: эхо-мина не «закрыта», она компенсируется деньгами — и, как показывает Д1, компенсируется НЕВИДИМО для отчёта.
  • П8 сработал, и его диагноз меняет адресата, а не статус. Парсер отверг строку Бам, бам-бам→Тук, тук-тук, у которой в src нет ни одного ханьца, — то есть исполнил свой контракт. Негодную строку выдала МОДЕЛЬ. Формулировка моего же критерия («парсер не принимает то, что модель выдаёт») оказалась неточной: она предполагала вину парсера. Критерий сработал, дефект — на стороне промпта/модели, и лечится строкой инструкции («src обязан быть исходным написанием»).

§10. ДЕВИАЦИИ ОТ ПРОМТА (отдельным разделом, как требует приёмка)

  1. Промт: «LOG_LLM_BODIES включить — записи парсера код выбрасывает, поэтому единственный способ увидеть САМИ предложения — сырые тела». Включил (LOG_LLM_BODIES=1 LOG_LEVEL=debug), но метод не сработал: тела режутся на 4096 байт и банкнота в хвосте не попадает в лог (Д3). Девиация: предложения извлечены из checkpoints.response_text первичных попыток — сырьё более прямое, чем лог. Предпосылка промта заодно опровергнута (Д4).
  2. Промт: «проба банкноты — ОТДЕЛЬНЫЙ проект, только волна черновика». Исполнено буквально. Дополнительно завёл третий микро-проект (minirun-rebill/, одна глава, только драфт) — промт этого не предусматривал, но требовал «проход с флагом» у rebill-гейта, а на главном проекте это стоило бы второй оплаты всего прогона ($0.114). Микро-проект дал тот же лег за $0.003.
  3. Пар-слой и промпты. rerun2 прописывал prompt_override и inline-segmentation; я вместо этого положил в проект КОПИЮ ратифицированного pairs/zh-ru.yaml с абсолютным prompts_root и гоню промпты КОНВЕНЦИЕЙ (prompts/<пара>/<роль>.md). Пар-данные сверены с репозиторным файлом: не-комментарные строки идентичны. Мотив — проверить штатный шов слоя 2, а не обходить его.
  4. escalation.budget_usd: 0.30 (rerun2 держал 3.0). Осознанно: на 10 главах бюджет должен позволять эскалации, но не финансировать их десятками.
  5. Второй арм (glm-5) НЕ гонялся — промт разрешает только по отдельному слову владельца. Не спрашивал.
  6. Владельцу задано ДВА вопроса вместо одного — майнинг-стоп очистился раундами (Д5). Первый: 学堂 (владелец рассмотрел «академию», подписал «школа» после того, как я принёс фактуру из исходника). Второй: 学堂家老 → «старейшина школы».
  7. Сессия НЕ коммитила — ни код, ни артефакты прогона (промт). Рабочее дерево бэкенда содержит гигиену ШАГА 0 незакоммиченной; книга и производные — вне git.

§11. ЧТО ПРОГОН НЕ ПРОВЕРИЛ (честнее списка успехов)

  • Качество перевода. Судья не звался (D39.32). Всё, что сказано выше про текст, — детерминированные сигналы и мои глаза на выборке, а не вердикт о читаемости. Планка «≤2 претензии владельца» этим прогоном НЕ адресовалась.
  • Масштаб. 10 глав из 2284 разделов. Ни каденс волн, ни поведение потолков/ETA на сотнях глав, ни деградация банка на длинной книге не проверялись. Цифра «остаток = 0» — про 14 единиц, а не про книгу.
  • Второй арм и итерация №2. dspro-vs-glm не сравнивались; вопрос «кто редактор» этим прогоном не двигался.
  • Петля ремонта. Осталась enabled: false. Мы измерили, СКОЛЬКО работы она нашла бы (ноль), но не проверили, что она делает эту работу правильно.
  • Атомарность reserve→settle под падением. Живого kill -9 не делал; инвариант держится косвенно (нет рваных состояний) и прямо — только тестом в CI.
  • Лейбл-путь под ЛЕЙБЛОМ. Доказано, что книга БЕЗ лейблов идёт байт-идентично; путь помеченной книги (маршрутизация, label_models, fail-closed) живьём не гонялся — помеченных книг нет.
  • Канал B / 18+. Не трогались (промт запрещает).
  • Эскалация дальше первого хопа. Случился ровно один хоп и он ответил; поведение цепочки при отказе ПЕРВОГО хопа (escalation_model на отказавшем хопе — кейс, ради которого пере-капчерился golden в паке-18) живьём не воспроизводилось.
  • Резюм после падения посреди волны. Все три остановки были штатными (майнинг-стоп, отказ гейта). Аварийного прерывания не было.
  • ja/en-пары. Инвариант общности §0 проверялся кодом и тестами (синтетический «второй пак»), но не живой книгой на другой паре.
  • Банкнота в шиппинг-форме. Проверен канал, а не продукт: dst по-прежнему выбрасывается кодом, майнинг-стоп по-прежнему отдаёт голые термы. Проба доказала, что чинить есть что и есть из чего.

§12. ЧТО ЛОЖИТСЯ НА ВЛАДЕЛЬЦА / В ОЧЕРЕДЬ

  1. Решение о платной петле ремонта (D39.24): чистый остаток в её классах — 0. Моя рекомендация — НЕ включать сейчас; вернуться к вопросу, когда появится выборка больше 14 единиц или когда классы петли расширятся.
  2. Шов банкноты (развилка D39.36): проба говорит «канал работает, предложения годятся как основа канона (~4045% полезных), и dst НЕ потерян — он в БД». Починка дешевле, чем считалось: пере-прогон не нужен.
  3. Д1 (эхо-метрика слепа к вылеченному эскалацией эху) — фикс дешёвый, но это правка кода: в пак-19 или отдельной мелочью.
  4. Д2 (редакторский max_tokens = флор модели, 15.5% денег в брак) — требует решения о том, откуда считать потолок редактора; двигает снапшот, поэтому едет с ближайшим resnapshot.
  5. Д6 (нет форм мн. ч. в сиде) и 族长 → род/клан — правки ДАННЫХ сида, зона владельца, $0.
  6. Д7 (11 ложняков из 11) — чистка чекеров: dialogue_dash не должен считать «мысль в «…»» смешением стилей; percent_scale не должен называть верный масштаб ошибкой масштаба.
  7. Сдвинутая ось langpack_version (a7d4be2c0465a28ed743c99c) — при следующем прогоне СТЕНДОВЫХ книг это часть уже состоявшегося расхождения D39.35, отдельной оплаты не создаёт.

§13. АРТЕФАКТЫ (для приёмки по сырью и ре-рана манифеста)

артефакт путь
главный проект /home/ubuntu/books/gu-zhenren/minirun/book.yaml, pipeline.yaml, pairs/zh-ru.yaml, guzhenren-minirun.db
логи главного прохода run-01-draft.log (стоп 1) · run-02-edit.log (стоп 2) · run-03-edit.log (edit-волна) · run-04-rebill-refusal.log
подписи mined-delta.yaml (2 терма) · mined-rejects.yaml (пусто) · guzhenren-minirun.db.mined-signature.yaml
проекции status-final.txt · status-final.json · report-final.txt · export.json · export.txt
проба банкноты /home/ubuntu/books/gu-zhenren/minirun-banknote/run-banknote.log, guzhenren-banknote.db, export-banknote.txt, prompts/zh-ru/translator.md (копия с блоком)
проба rebill-гейта /home/ubuntu/books/gu-zhenren/minirun-rebill/run-01-baseline.logrun-05-accept.log, guzhenren-rebill.db
бэкап фактуры rerun2 /home/ubuntu/books/gu-zhenren/backup-pre-minirun-2026-07-25/
код гигиены (НЕ закоммичен) backend/: configs/pipeline-*.yaml, configs/langpacks/zh-ru/dc-checkers.txt, internal/lang/langpack.go, internal/checks/{checkers.go,cheapgates.go}, internal/pipeline/status.go, cmd/tmctl/render.go + 3 новых тест-файла

Ре-ран манифеста приёмки (всё $0):

cd backend && go build ./... && go vet ./... && go test ./... -race
sha256sum internal/pipeline/testdata/golden/capture.golden   # 211c9013…089045d6 == HEAD
grep -rh '^func Test' --include=*_test.go . | wc -l          # 483 (было 475, удалено 0)
tmctl status --config /home/ubuntu/books/gu-zhenren/minirun/book.yaml
tmctl report --config /home/ubuntu/books/gu-zhenren/minirun/book.yaml
tmctl export --config /home/ubuntu/books/gu-zhenren/minirun/book.yaml --plaintext

§14. ФИКС-ПАК ПО ИТОГАМ ПРОГОНА (та же сессия, санкция владельца: «исследование → правки → ревью»)

Четыре дефекта починены, два кандидата на починку сознательно ОТКЛОНЕНЫ по итогам исследования — и это главный результат раздела: правка, умершая о ратифицированную фикстуру, дешевле правки, которая её тихо переписала.

14.1 Что построено

# Фикс Форма Сдвигает снапшот?
Д1 chunk_status.first_flag_reason (миграция v11) + echo_draft считает эхо, вылеченное эскалацией; новое поле echo_draft_recovered держит число честным в обе стороны код + схема нет
Д4 retrieval_state.banknote_detail (та же v11) — распарсенные записи банкноты durable; майнинг-стоп джойнит их в подписную карту: dst = самое частое предложение, альтернативы с весами в note, status: auto НЕ трогается код + схема нет
Д7a dialogue_dash больше не считает смешением стилей строку, чья атрибуция — глагол ВНУТРЕННЕЙ речи (данные таргета inner_speech) код + target-данные да (CheapGateVersion v4→v5)
Д3 LOG_LLM_BODIES: кап 4096→32768 байт и обрезка СЕРЕДИНЫ, а не хвоста — блок банкноты живёт в хвосте ответа код нет
Д2 флор deepseek-v4-pro 8000→16000 по замеру (перебор бюджета бесплатен, недобор стоит целой генерации) данные models.yaml да (max_tokens ∈ request_hash)

Ключевая находка исследования, удешевившая Д4: сырой текст банкноты УЖЕ durable в чекпоинте, а resume его пере-парсит (stagerun.go resume-path) — поэтому новая таблица не нужна, хватило четвёртой *_detail-колонки рядом с тремя такими же.

Граница безопасности Д4 названа явно: предложенный dst приезжает как ЕВИДЕНС на терме status: auto. Trust-gate (D39.2) в инъекцию пускает только CONFIRMED, значит «модель предложила» не может само стать «книга использует». Развилки D39.36 п.2/п.3 (опциональный ОК, ослабление trust-gate) НЕ трогались — это продуктовое решение владельца.

14.2 Что ОТКЛОНЕНО и почему (обе правки были написаны, прогнаны и откачены)

  • percent_scale. Мой отчёт назвал 2 живых срабатывания ложняками (масштаб верен, форма — дробь). Правка «стрелять только на ЦИФРОВОЙ форме» уронила ратифицированную фикстуру «шесть и шесть десятых» = 6.6 для 六成六 — это НАСТОЯЩАЯ 100× ошибка, и она тоже прописана словами. То есть цифро-словесная граница не разделяет классы; разделяет ЗНАЧЕНИЕ, а для него нужен разбор числительных таргета в данные. Правка откачена, дизайн записан.
  • dc2 千万. Живое срабатывание (杀了千万人 → «тысячи и тысячи людей») шейпом тождественно ратифицированному ИСТИННОМУ (千万生灵 → «тысячи жизней»). Вето по коэффициенту убивало оба. Вывод, который правит мой же §6.2: это не дефект реализации, а принятая неоднозначность класса, о которой предупреждает его собственный комментарий (§5-A4). Правка откачена.

⇒ чистый остаток ложняков после фикс-пака: 8 из 11 закрыты (dialogue_dash), 3 остаются осознанно — 2 percent_scale (ждут числительных в данных) и 1 dc2 (offline неразделим).

14.3 Ревью исполнением

проверка результат
build / vet / gofmt чисто (единственная жалоба internal/llm/llm.go воспроизводится на HEAD — файл не трогался)
go test ./... -race 15 пакетов green, 0 FAIL
golden пере-капчер САНКЦИОНИРОВАННЫЙ и доказанный: 172 сырых строки сдвинулись, но МАСКИРОВАННЫЙ структурный дифф (хеши→<HASH>, версия→<CHEAPGATE_VERSION>) ПУСТ ⇒ двигались только версии и производные от них хеши, ни один вердикт/текст/стоимость не изменились. 211c9013…089045d61165e3a9…2132ea82
ценз ИМЁН тестов 483 → 491, удалено 0
мутации 6 мутаций — 6 красных: echo-метрика читает только вердикт · first_flag_reason пишется и когда он И ЕСТЬ вердикт (двойной счёт) · записи банкноты снова выбрасываются · подписная карта перестаёт нести dst · дискриминатор внутренней речи выключен · обрезка лога снова хвостовая
проверка на ЖИВЫХ данных прогона реальные 9 блоков банкноты из БД пробы прогнаны через НОВЫЙ шов: 71 строка, 67 различных ключей, 2 терма с конкурирующими вариантами. Среди них — 学堂家老, тот самый, который владелец сегодня подписывал вслепую: под фиксом карта пришла бы с dst: «старейшина школы» (+ «старейшина-наставник», «учитель-старейшина» в note) — ровно тем вариантом, который владелец и выбрал

Честная граница этой проверки: $0-реплей ПОЛНОГО прогона через новый код невозможен — правки Д7a/Д2 двигают снапшот, и job-пиннинг корректно отказал («already-paid checkpoints become invalid»). Это не дефект, а работающая дисциплина; поэтому живьём проверены ПУРЕ-функции нового шва на реальных ответах, а сквозняк — тремя тестами через настоящий драйвер.

14.3-bis МОЯ ОШИБКА В ХОДЕ РЕВЬЮ: непреднамеренная трата $0.046668

Проверяя, что миграция v9→v11 чисто ложится на БД стендовой схемы, я собрал book.yaml, указывающий на КОПИЮ rerun2-БД, но оставил в нём источник и пайплайн мини-прогона. Для движка это была НОВАЯ книга (строк guzhenren-minirun в той БД нет) — и он честно начал переводить. Прогон шёл ~5 минут до моего таймаута.

Точный счёт (по строкам БД-копии): guzhenren-minirun / 2026-07-25 → $0.046668, 31 живой вызов. Деньги потрачены зря.

Что НЕ пострадало (проверено): оригинальная rerun2/guzhenren-rerun2.db — схема по-прежнему v9, единственный book_id = guzhenren-rerun2, spend не изменился · бэкап 25.07 цел · БД мини-прогона и пробы банкноты нетронуты (v10, свои суммы). Трата целиком осталась на выбрасываемой копии в скретчпаде.

Что проверка всё же дала: миграция v9→v11 применилась чисто (schema_version 1…11, обе колонки на месте, старые строки целы) — ради этого она и затевалась; и в логе видно max_tokens=16000 на живом вызове редактора, то есть фикс Д2 подтверждён исполнением.

Правильный способ, которым надо было это делать: открывать стор на запись командой, которая гарантированно не доходит до провайдера (или на БД, где книга уже завершена), а не собирать конфиг «чужая БД + чужой источник».

Итог по деньгам сессии: $0.139060 (прогон + проба + гейт) + $0.046668 брака ревью = $0.185728.

14.4 Цена следующего прогона

Две оси версий сдвинуты осознанно: style_check_version (v4→v5) и max_tokens через флор dspro. Обе входят в снапшот ⇒ следующий платный прогон стендовой книги пере-оплачивается целиком и потребует --resnapshot --accept-rebill. На сегодня это ничего не стоит: мини-прогон закрыт, а стендовый снапшот и так разошёлся (D39.35). Экономия от Д2 (≈15% счёта на браке) окупает пере-пин на первом же прогоне.


§15. СКВОЗНАЯ ПРОВЕРКА БЭКЕНДА ПОСЛЕ ФИКС-ПАКА (26.07, по вопросу владельца «а ты протестировал?»)

Вопрос был законный: после фиксов я прогнал ТЕСТЫ, но не гонял БЭКЕНД. Прогнал — два проверочных прогона, $0.049, и они нашли то, чего тесты не могли.

15.1 Что проверено живьём

Проект minirun-verify (главы 12) и minirun-verify2 (главы 45, выбраны потому, что там ЕСТЬ майнинг-кандидат), оба с включённой банкнотой — иначе главный фикс не отрабатывает.

узел результат
миграция v11 на свежей БД схема 1…11, обе новые колонки на месте
ingest → чанкер 2 главы → 4 драфт-чанка → 3 edit-единицы
драфт-волна с банкнотой n_banknote_lines 7 и 3, banknote_detail записан живьём (396 и 193 байта)
майнинг-стоп выстрелил, 2 терма, подписная карта записана
подпись → резюм стоп очистился, драфт резюмнулся за $0, edit-волна прошла 3/3
санитайзер поймал РЕАЛЬНЫЙ дефект: mixed Cyrillic and Latin in one word (homoglyph): лицó
RegressionGuard ПЕРВОЕ ЖИВОЕ СРАБАТЫВАНИЕ: number_drift [66] — черновик писал «66%», редактор «шестьдесят шесть процентов». Значение цело, цифра ушла ⇒ это ровно тот ложняк, который предсказан в его собственной доке. Гейт, невключённый до 25.07, теперь даёт сигнал
банк памяти 56 попаданий + 12 sticky, 2 промаха пост-чека
экспорт 31 715 байт, сепаратор банкноты в отгруженном тексте 0 раз
деньги $0.032764 из потолка $0.30, finish=stop на всех вызовах

15.2 Что нашёл ТОЛЬКО сквозной прогон

(1) Поправка к тому, что я сказал владельцу вчера. Я утверждал: «под фиксом подписная карта пришла бы с dst «старейшина школы» — ровно тем, что владелец выбрал». Верно только для ВТОРОЙ подписи. Проверка по сырью пробы: банкнота НИКОГДА не предлагала 学堂 отдельно — только составной 学堂家老. Значит раунд 1 всё равно пришёл бы голым.

(2) Структурный разрыв, из-за которого фикс даёт меньше, чем кажется. На verify2 стоп выстрелил с terms_with_proposed_dst=0: майнер предложил 花海 и 陈博, банкнота — 古月方源, 学堂家老, 开窍大典, 力量蛊, 智慧蛊, 灵泉. Пересечение НУЛЕВОЕ. Механизм джойна исправен (ключи нормализуются верно), но два канала систематически выбирают РАЗНЫЕ популяции: майнер — частотные name/place/title (freq ≥ 5), банкнота — то, что модель считает новой терминологией. Итог: на 10 главах шов помог бы в 1 подписном раунде из 2, на 2 главах — в 0 из 1. Следующая работа по банкноте — не «замкнуть шов» (замкнут), а заставить WHAT покрывать кандидатов WHICH (например, инъекция списка mined-кандидатов в промпт переводчика).

(3) Полярность дискриминатора чекера была выбрана неверно — исправлено по живым данным. Первая версия спрашивала «это МЫСЛЬ?» по списку глаголов мысли. Живой прогон за минуты выдал «понимал» и «размышлял», которых в списке нет: список мыслей не имеет естественной границы, и каждый промах = ложный флаг на хорошей прозе. Перевернул: «это РЕЧЬ?» по закрытому списку речевых глаголов + вето про себя/мысленно (нашлось на «пробормотал про себя»). Промах теперь = МОЛЧАНИЕ, а не флаг — та ошибка, которую и требует ратифицированный уклон precision-over-recall. Замер по реальным экспортам, по чанкам: мини-прогон 10 глав 8 → 0, проверка 2 глав 1 → 0, при этом настоящее смешение речи («…», — сказал он) по-прежнему флагается.

(4) Дыра в моих же тестах, вскрытая мутацией. Мутация «снять nil/no-data гард» ВЫЖИЛА: ветка «книга без данных таргета» была не покрыта, а без гарда там nil-разыменование. Закрыто тестом TestLintDialogueDashInertWithoutTargetData (nil-спека и спека без данных: правило молчит, но его data-independent половина — дефис вместо тире — продолжает работать). Пере-мутация после этого — красная с паникой.

15.3 Ревью финального состояния

build/vet/gofmt чисты · -race 15/15 · golden пере-капчен ВТОРОЙ раз (точное имя версии cheapgate-v5-chevron-speech-attribution), маскированный структурный дифф снова ПУСТ281d7025…dd9b99b4 · ценз ИМЁН 475 → 492, удалено 0 · 9 мутаций суммарно — 9 красных (три последние по новому правилу; одна выжила, вскрыла дыру, дыра закрыта, пере-мутация красная).

Деньги проверки: $0.032764 + $0.016091 = $0.048855. Итог сессии: $0.139060 (прогон) + $0.046668 (мой брак) + $0.048855 (сквозная проверка) = $0.234583.