From e86b34ce6aa4dabac15fb94fd80b5cd8ef1ced14 Mon Sep 17 00:00:00 2001 From: heaven Date: Fri, 11 Sep 2026 14:57:52 +0300 Subject: [PATCH] Divide the money by the copies that multiplied it, let the shape gate see the row it was blinded on, and stop the order asking for an effort step that does not exist --- ...KEND_FAILURE_YOU_CAN_SEE_SESSION_PROMPT.md | 42 +++++++++++++++---- docs/BACKLOG.md | 11 ++--- docs/scripts/counts.py | 4 +- 3 files changed, 43 insertions(+), 14 deletions(-) diff --git a/docs/BACKEND_FAILURE_YOU_CAN_SEE_SESSION_PROMPT.md b/docs/BACKEND_FAILURE_YOU_CAN_SEE_SESSION_PROMPT.md index e892a87f..bb4527b7 100644 --- a/docs/BACKEND_FAILURE_YOU_CAN_SEE_SESSION_PROMPT.md +++ b/docs/BACKEND_FAILURE_YOU_CAN_SEE_SESSION_PROMPT.md @@ -134,6 +134,24 @@ | **размышление съело потолок** | 2-я попытка дала МЕНЬШЕ, чем потолок 1-й (`edit`: 11717 < 16000) | удвоить — то есть дать размышлению вдвое больше места | **ступень эффорта ниже при ТОМ ЖЕ потолке** — но см. ⛔ ниже, величина не замерена | | `length` **с текстом** | обрезок доехал | удвоить | **оставить как есть** — это ровно решение `D2` | +⛔⛔ **ДВЕ ПОПРАВКИ К ТАБЛИЦЕ, СНЯТЫЕ ЗАМЕРОМ 11.09 — читай их прежде, чем исполнять её.** + +**(а) «Ступень эффорта ниже» СЕГОДНЯ ВЫРОЖДЕНА НА ВСЕХ БОЕВЫХ ЗНАЧЕНИЯХ.** Замер: во всех четырёх живых +`configs/pipeline-*.yaml` значений `reasoning:` **двенадцать**, и все — `low` (7) или `off` (5). Словарь +движка упорядочен `"" · off · low · medium · high` (`ValidReasoningEffort`), и **ниже `low` эмитирующей +ступени НЕТ**: `off` и пустая строка не эмитят ничего, то есть едет вендор-дефолт `high` — это БОЛЬШЕ +размышления, а не меньше. ⇒ шаг вниз по нейтральному словарю на сегодняшнем конфиге некуда сделать. +Носитель дорогого случая (`edit`) стоит именно на `off`. **Из трёх законных выходов §4.1 первый +(«шаг вниз по нейтральному словарю») снимается как вырожденный**, пока боевые значения такие; остаются +второй (решать через оценку первого потолка) и третий (пер-модельная таблица — только пингом до кода). + +**(б) ОДНА ЕДИНИЦА ПРОГОНА ПОПАДАЕТ В ДВЕ СТРОКИ ТАБЛИЦЫ СРАЗУ, и приоритета в ней не было.** +`draft` ch2u1 (`degraded='length'`, обрезок с текстом, ретрай дал **13004 > 8496**) удовлетворяет и строке +«потолок мал» (2-я попытка больше потолка 1-й), и строке «`length` с текстом → оставить как есть». ⇒ +**приоритет задаю: строка «`length` с текстом» применима ТОЛЬКО если ретрай уложился в СТАРЫЙ потолок.** +Не уложился — значит потолка и вправду не хватало, и побеждает первая строка. Иначе единственный носитель +третьей строки уходит в неё же и класс остаётся непроверяемым. + ⛔ **ЧЕГО В ТАБЛИЦЕ НЕТ И НЕ ДОЛЖНО БЫТЬ: «не перевыпускать».** На замеренных данных это стоило бы трёх восстановленных чанков из четырёх и отменяло бы `D2` п.2. Вопрос — в ЦЕНЕ попытки, а не в её отмене. @@ -170,6 +188,11 @@ a named finding, not a silent gap». ⇒ **пер-модельная табли `reasoning_effort`; ничего не эмитят только `off` и пустая строка, и тогда едет вендор-дефолт `high`. Именно `off` стоит у редактора в `backend/configs/pipeline-c1.yaml` — **это ВЫБОР конфига, а не невозможность.** Проверь чтением `internal/llm/capability.go` сама. +⛔ **И ПРЕЖДЕ ЧЕМ ЧИТАТЬ БОЕВОЙ КОНФИГ — он несёт ОТОЗВАННЫЙ вендорский клейм.** + `backend/configs/pipeline-c1.yaml:86`=`v4-pro maps low` дословно: «v4-pro maps low→high, effective effort + unchanged». Это было верно до 30.08 и ОТОЗВАНО квирками: вендор сменил маппинг, и `low` на `pro` теперь + даёт `low`. Комментарий в дереве живёт, читатель ему верит. **Носитель поправки — ряд бэклога 429**; + правка самого комментария в твоём паке НЕ заказана, но не наследуй его как факт. * **«На pro рычага нет» больше не правда.** Вендор сменил маппинг; полигон снял поведенческую пробу 30.08 за $0.038276 и показал, что `low` до `pro` доходит. Живая запись — квирки §3г. * ⇒ **ось «`off` против `low`» измеряется ОТДЕЛЬНЫМ КОНФИГОМ КНИГИ. Это ДАННЫЕ**: ни правки Go, ни снятия @@ -189,9 +212,9 @@ a named finding, not a silent gap». ⇒ **пер-модельная табли ### 4.3. `reasoning_tokens` не несла числа ни разу · «реши сама и аргументируй» -Замер оркестратора 11.09: `request_log.reasoning_tokens > 0` — **0 строк**. Контроль рядом: найдено -**448** файлов `*.db`, таблицу `request_log` несут **405**, прочитано **58 886** строк, колонка объявлена -схемой и присутствует во всех. ⇒ единственная колонка, которой доказывают «потолок съело рассуждение», +Замер оркестратора 11.09: `request_log.reasoning_tokens > 0` — **0 строк**. Контроль рядом: найдено **449** файлов `*.db`, прочитано **58 886** +строк-экземпляров, и ⛔ **уникальных из них 5 413** — свод обходом диска умножает счёт на число копий базы +в **10.88** раза (ряд **428**); ноль устоял и на честном знаменателе. Колонка объявлена схемой и присутствует во всех. ⇒ единственная колонка, которой доказывают «потолок съело рассуждение», структурно молчит, и её ноль неотличим от «рассуждения не было». Причина известна и не баг нашего кода: DeepSeek считает рассуждение внутри `completion_tokens` и отдельным @@ -218,11 +241,14 @@ a named finding, not a silent gap». ⇒ **пер-модельная табли ### 4.5. Цена считается по модели, которой нет в каталоге · «делай РОВНО так» в части замера, «реши сама» в части лечения -Замер оркестратора 11.09 по всем базам машины (контроль: 448 файлов `*.db`, 405 с `request_log`, 58 886 -строк): **365 строк оплачены ПОДСТАНОВКОЙ** — провайдер вернул слаг, которого в каталоге нет. ⚠ Из них -**344 боевые** (`deepseek-v4-flash` → `deepseek-flash`, 296 строк, $2.049737; `local-qwen3-8b` → -`huihui_ai/qwen3-abliterated:8b`, 48 строк, $0) и **21 — тестовые фикстуры** (`m-req`→`m-act`, -`fake-model`), которые обязаны быть вычтены: иначе $5.51 фикстуры уедут в денежный вывод. +Замер оркестратора 11.09, пере-снятый 11.09 же ⛔ **после того, как первая редакция этих чисел оказалась +завышенной в 10.88 раза моей собственной ловушкой** (ряд **428**: свод обходом диска умножает трату на число +копий базы). Честный контроль: баз открыто **449**, строк-экземпляров **58 886**, **УНИКАЛЬНЫХ строк 5 413**. +После дедупа по идентичности строки подстановкой оплачено **70 строк**, из них **боевых 65**: +`deepseek-v4-flash` → `deepseek-flash` — **28 строк, $0.188953**; `local-qwen3-8b` → +`huihui_ai/qwen3-abliterated:8b` — **37 строк, $0**. Фикстур **5** на **$0.424277** (`m-req`→`m-act` 1, +`fake-model` 4) — их вычитать. ⚠ Если увидишь где-то «365 · 344 · 21 · $2.049737 · $5.51» — это моя +протухшая редакция, не наследуй её. **Сегодня это безвредно:** подстановка падает на ЗАПРОШЕННУЮ модель той же семьи. ⛔ Опасна не подстановка, а её молчание. `PriceForResponse` (`internal/ledger/pricing.go:61`=`func (p *Pricer) PriceForResponse`) пробует `actual`, потом `requested`, diff --git a/docs/BACKLOG.md b/docs/BACKLOG.md index 572f11ac..c5a2da35 100644 --- a/docs/BACKLOG.md +++ b/docs/BACKLOG.md @@ -3,7 +3,7 @@ > **Единственный трекер проекта.** Здесь живут строки, на которые доки, промты и D-ноты ссылаются словами «строка N» / «строка бэклога N»: **ID строки стабилен навсегда**, не перенумеровывается и не переиспользуется (D39.80). Правки — только через оркестратора; каждая петля обязана иметь диспозицию: решено / отложено-с-записью / отклонено. > ⚠ **Это НЕ бэклог зоны `docs/`, а бэклог ПРОЕКТА.** У зон свои, с другими неймспейсами ID, и единый их строк не принимает (D39.84): платформа — [../platform/BACKLOG.md](../platform/BACKLOG.md) (`П-N`) и её регистр дефектов `platform/docs/DEFECT_REGISTER.md` (`PD-N`); фронт — [../frontend/docs/BACKLOG.md](../frontend/docs/BACKLOG.md) (`Ф-N`). > ⚠ **Состояние проекта — не здесь.** Очередь, курс, CURRENT-STATE, состояние паков и живая хроника — шапка [PROGRESS.md](PROGRESS.md). Здесь только долг и его диспозиции. -> - **СЧЁТ ОЧЕРЕДИ на 11.09 (скриптом по таблице — `python3 docs/scripts/counts.py`; обновлять при каждом лендинге):** всего **312** строк · зона бэкенд **150** строго / **204** широко (⚠ колонки счётчик читает С КОНЦА — испр. D39.116) · **блокеров очереди 0** (236 закрыта D39.175; **371** — актом D39.233, **360** — актом D39.232, обе 10.09), платные прогоны разблокированы · «скоро» **157** (перечень — грепом по таблице, рукописный список снят D39.126) · гейт-строка эксп-22: 153 (плюс 150 — руки владельца; ⚠ 55 из гейтов СНЯТА — D39.198 п.5); строка 5 — остаток гейчен ре-пробой 74, носитель события теперь строка 188 (аудит D39.140); остальное «когда-нибудь». ⚠ Счёт — НИЖНЯЯ граница долга, не потолок (разбор — легенда таблицы ниже). +> - **СЧЁТ ОЧЕРЕДИ на 11.09 (скриптом по таблице — `python3 docs/scripts/counts.py`; обновлять при каждом лендинге):** всего **313** строк · зона бэкенд **151** строго / **205** широко (⚠ колонки счётчик читает С КОНЦА — испр. D39.116) · **блокеров очереди 0** (236 закрыта D39.175; **371** — актом D39.233, **360** — актом D39.232, обе 10.09), платные прогоны разблокированы · «скоро» **158** (перечень — грепом по таблице, рукописный список снят D39.126) · гейт-строка эксп-22: 153 (плюс 150 — руки владельца; ⚠ 55 из гейтов СНЯТА — D39.198 п.5); строка 5 — остаток гейчен ре-пробой 74, носитель события теперь строка 188 (аудит D39.140); остальное «когда-нибудь». ⚠ Счёт — НИЖНЯЯ граница долга, не потолок (разбор — легенда таблицы ниже). > - ⚠ **Переезд 06.09 (D39.218):** таблица вынесена из `PROGRESS.md` ДОСЛОВНО и ни один ID не сдвинут — **с единственным исключением: две ячейки (строки 220 и 306) тронуты РОВНО в номере якоря `docs/scripts/counts.py:566`→`:569` и `:592`→`:595`**, потому что цель сдвинул этот же коммит; текст ячеек не менялся, длины равны. В `PROGRESS.md` на прежнем месте оставлен заголовок-указатель, поэтому ссылки «секция „Бэклог“» доезжают в один хоп. ## Бэклог (ЕДИНЫЙ, собран 26.07, актуализация 04.08 D39.99/D39.101; правки — только через оркестратора) @@ -333,7 +333,7 @@ | 410 | ⚠ **ПЕРЕПИСАН 11.09 — ПРЕЖНЯЯ ГОЛОВА БЫЛА НЕВЕРНА. Голос НЕ «мёртв в четырёх местах»: он ПОСТРОЕН СКВОЗЬ И ВЫКЛЮЧЕН ДВУМЯ ТУМБЛЕРАМИ.** Пере-снято мною прибором 11.09. **Построено:** схема сида несёт голос (`internal/seed/seed.go:25`=`Voices []Voice`, `Voices []Voice \`yaml:"voices"\``) · загрузчик секции есть (`membank/memvoice.go:79`=`func loadVoiceSections` `loadVoiceSections`, профиль собирается на `:121`) · хранилище есть (`store.VoiceProfilesForBook`, порядок пинован `bankmaterialize.go:214`) · инъекция в банк построена и УСЛОВНА (`membank/memory.go:511`=`if !in.InjectVoice` по `BankInput.InjectVoice`) · флаггер судит ОТГРУЖЕННЫЙ текст (`pipeline/voicerun.go:42`=`runVoiceChecks runs the voice flagger`) и печатает число в отчёт качества (`pipeline/quality.go:126`=`VoiceFlags int` `voice_flags`) · у гейта есть ручка и потребитель в Go (`quality.go:492`, `voicerun.go:46` по `Gates.Voice.Enabled`). **Выключено ровно двумя вещами.** ⛔ **(1) ДАННЫХ НЕТ НИ ОДНОЙ СТРОКИ, и знаменатель прежней записи был не тот.** Пере-снято: секция `voices:` встречается в **22** файлах дерева, и все 22 ПУСТЫ (не «21 из 22») — но все 22 суть МАШИННЫЕ выгрузки (`*.mined-signature.yaml`, `*.auto-bank.yaml`), то есть их пустота лишь пересказывает «майнер профили не эмитит» и самостоятельной уликой не является. Настоящий знаменатель — **22 рукописных сида с `terms:`, и ключа `voices:` нет НИ В ОДНОМ** (контроль: прибор прочёл 47 файлов с `terms:`, из них 25 машинных отброшены по имени). ⇒ за всю историю проекта профиль голоса не написал никто. **(2) `InjectVoice` — константа `false` без ключа конфига**, и комментарий `pipeline/bankmaterialize.go:295`=`InjectVoice is FALSE and has no config knob` называет и причину (`D21` п.2 держит инъекцию до полигонного замера), и ЦЕНУ включения: «Wiring the injection means setting it and accepting a full --resnapshot». Третьим, помельче: `gates.voice` не выставлен ни в одном из четырёх живых конфигов (контроль: соседние ключи `banknote`, `terminology`, `coverage`, `sanitizer`, `regression_guard` выставлены — прибор спрошен у существующего предмета). ⭐ **ВОПРОС ВЛАДЕЛЬЦУ СНЯТ ЕГО ЖЕ СЛОВОМ 11.09: «Входит»** — голос входит в приоритет №1 наравне с терминами; **проектирует и контролирует голос старший коллега (Fable 5), исполняет опус**, и пак обязан велеть сессии обсудить имплементацию с ним. Второй вопрос связки («если не подпись профилей, то кто») тоже снят: `D39.144` — подписывается банк ЦЕЛИКОМ, пер-профильной подписи в модели продукта нет. ⇒ **строка из вопроса стала ЗАДАЧЕЙ, и она мельче, чем читалась: не «построить голос», а написать профиль, открыть ручку и заплатить ре-снапшотом.** ⚠ Числа у механизма по-прежнему нет ни одного — первый замер обязан идти ПЕРЕД включением | бэкенд/владелец | **скоро** | профиль в сид · ключ конфига вместо константы · замер флаггером по отгруженному тексту; форму проектирует Fable 5 | аудит банка 11.09 (`research/34` §2.5, §4 п.2); голова ИСПР. 11.09 пере-замером оркестратора, слово владельца 11.09 | | 411 | ⛔ **КНИГУ, КОТОРУЮ ПАЙПЛАЙН ПЕРЕВОДИТ БЕСПЛАТНО, ПЛАТФОРМА ПРОДАТЬ НЕ МОЖЕТ — и это закрывает деплой на локальном инференсе целиком.** Замерено исполнением на стенде 11.09 (фаза 0 холодного прогона A): на $0-паре `step_max_usd` выходит 0, `ingest.Manifest.priced()` отказывает при `StepMaxUSD <= 0`, старт получает **`409 not_priced`**, в логе ERROR «this book has no price projection, so it cannot be sold». ⇒ **ни одна книга не продаётся, если её перевод ничего не стоит.** Для полигона это обходится номинальной ценой локальной модели отдельным файлом моделей (объявленная девиация), но для ПРОДУКТА это утверждение о рынке: развёртывание на своём железе — а именно им продаётся приватность и дешевизна — сегодня не может принять ни одного заказа. ⚠ Класс ошибки — «ноль цены прочитан как отсутствие цены»: предикат отвечает на свой вопрос («есть ли смета»), а спрошено другое («стоит ли это денег»). Лечение — решение о том, чем платформа меряет продаваемость, а не правка предиката | платформа | скоро | различение «цена ноль» и «сметы нет»; слово о деплое на локальном инференсе | фаза 0 прогона A, 11.09 | | 412 | **ШАБЛОН КНИГИ ИЗ РЕЦЕПТА СТЕНДА РОНЯЕТ КАЖДЫЙ СТАРТ БОЕВОГО КОНФИГА — молча для доков, громко для прогона.** Замерено 11.09: без ключа `langpack_root` движок отказывает на старте с **exit 10** и текстом «gates.terminology is enabled but this book cannot mine a bank: it needs a langpack». Ключа нет ни в `backend/example/book.yaml`, ни в рецепте `platform/docs/STACK_DECISIONS.md` §«Стенд разработчика», ни в рантбуке. ⇒ любой, кто соберёт книгу по нашему же рецепту и включит `c1`, получит отказ на старте — $0 по деньгам, но на ПЛАТНОЙ книге это потерянная «холодность» эксперимента, а на боевой выкатке — невозможность стартовать. Родня строки **251** (артефакт контраста): оба требования боевого банкового контура живут в коде и не доехали до носителей, по которым разворачивают | бэкенд+платформа | скоро | ключ в примере книги и в рецепте стенда; проверка полноты шаблона на буте | фаза 0 прогона A, 11.09 | -| 413 | ⛔⛔ **ЧИТАТЕЛЬ ПЛАТИТ ПО НАШЕМУ ПИНУ, А ПИН FLASH ПРОТУХ НА 13 % — и рядом НЕ РАЗРЕШЁННЫЙ вопрос, та ли это вообще модель.** Замерено полигоном на живом платном прогоне 11.09 и пере-проверено вендор-докой дважды (`api-docs.deepseek.com/quick_start/pricing`, гардрейл «идём в официальную доку, не гадаем»): наш пин `backend/configs/models.yaml:218`=`ПИК с 16.08.2026 16:00 UTC` держит flash `$0.44 in / $1.32 out / cache-hit $0.014` от **16.08.2026**, вендорская таблица сегодня даёт **`0.30 / 1.20 / 0.006`**; у `pro` пин совпадает ТОЧНО. Арифметика движка безупречна — по нашему пину прогон сходится до нуля микро-долларов, — но по вендорским числам тот же прогон стоил бы **$0.397246 против $0.419424**, то есть **пин завышает на $0.022177 = 5.6 % книги, ×1.133 по flash**. ⇒ мы выставляем читателю СВОЁ число, и оно выше провайдерского. ⛔ **Половина, без которой цену править НЕЛЬЗЯ:** `model_requested` = `deepseek-v4-flash`, а `model_actual` = **`deepseek-flash`** на 28 строках из 33, и слага `deepseek-flash` в нашем `models.yaml` НЕТ — вендорская прайс-таблица называет модель именно так. По правилу «слаг живой ≠ модель та же» замерено, что имена разные; НЕ установлено, алиас это или другая модель. Сперва identity, потом цена. ⛔ **ДОПОЛНЕНО 11.09 ПЕРЕ-ЗАМЕРОМ ОРКЕСТРАТОРА — под рядом лежит ВТОРАЯ беда, и она про МОЛЧАНИЕ, а не про число.** Замер по всем базам машины ⚠ (контроль ИСПР. 11.09 после пере-замера через `find`: файлов `*.db` **448**, с таблицей `request_log` **405**, прочитано **58 886** строк — первый счёт был занижен `glob`-ом): **365 строк оплачены ПОДСТАНОВКОЙ цены, из них 344 боевые и 21 тестовая фикстура** (`m-req`→`m-act` 13, `fake-model` 8 — их надо вычитать, иначе $5.51 фикстуры попадут в денежный вывод) — провайдер вернул слаг, которого в каталоге нет, — `deepseek-v4-flash` → `deepseek-flash` (296 строк, $2.049737) и `local-qwen3-8b` → `huihui_ai/qwen3-abliterated:8b` (48 строк, $0). **Сегодня это безвредно:** подстановка падает на ЗАПРОШЕННУЮ модель той же семьи, и пин верен по семье. ⛔ Опасна не подстановка, а то, что о ней **никто не узнаёт**: `PriceForResponse` (`backend/internal/ledger/pricing.go:61`=`func (p *Pricer) PriceForResponse`) пробует `actual`, потом `requested`, потом якорь, и ни одно из ТРЁХ мест вызова не различает, какая ветвь сработала. Комментарий там же охраняет РОВНО ОДНО направление («премиальный ответ не должен биться по дешёвому дефолту»); обратное — когда провайдер маршрутизирует ВНИЗ — не охраняет никто: запрошен `pro`, ответила модель дешевле, счёт идёт по пину `pro`, $3.96 за 1M выходных против $1.20 вендорских у flash = **×3.3 из кармана читателя, молча**. ⇒ лечение двухчастное: завести слаг, который провайдер РЕАЛЬНО возвращает, и сделать срабатывание подстановки ВИДИМЫМ. Носитель работы — пак «падение, которое видно» §4.5 | бэкенд+полигон | **скоро** | вендор-сверка identity слага, затем пере-пин с датой и способом в формулировке; отдельно — наблюдаемость подстановки | критик чисел прогона A, 11.09; подстановка — пере-замер оркестратора 11.09 | +| 413 | ⛔⛔ **ЧИТАТЕЛЬ ПЛАТИТ ПО НАШЕМУ ПИНУ, А ПИН FLASH ПРОТУХ НА 13 % — и рядом НЕ РАЗРЕШЁННЫЙ вопрос, та ли это вообще модель.** Замерено полигоном на живом платном прогоне 11.09 и пере-проверено вендор-докой дважды (`api-docs.deepseek.com/quick_start/pricing`, гардрейл «идём в официальную доку, не гадаем»): наш пин `backend/configs/models.yaml:218`=`ПИК с 16.08.2026 16:00 UTC` держит flash `$0.44 in / $1.32 out / cache-hit $0.014` от **16.08.2026**, вендорская таблица сегодня даёт **`0.30 / 1.20 / 0.006`**; у `pro` пин совпадает ТОЧНО. Арифметика движка безупречна — по нашему пину прогон сходится до нуля микро-долларов, — но по вендорским числам тот же прогон стоил бы **$0.397246 против $0.419424**, то есть **пин завышает на $0.022177 = 5.6 % книги, ×1.133 по flash**. ⇒ мы выставляем читателю СВОЁ число, и оно выше провайдерского. ⛔ **Половина, без которой цену править НЕЛЬЗЯ:** `model_requested` = `deepseek-v4-flash`, а `model_actual` = **`deepseek-flash`** на 28 строках из 33, и слага `deepseek-flash` в нашем `models.yaml` НЕТ — вендорская прайс-таблица называет модель именно так. По правилу «слаг живой ≠ модель та же» замерено, что имена разные; НЕ установлено, алиас это или другая модель. Сперва identity, потом цена. ⛔ **ДОПОЛНЕНО 11.09 ПЕРЕ-ЗАМЕРОМ ОРКЕСТРАТОРА — под рядом лежит ВТОРАЯ беда, и она про МОЛЧАНИЕ, а не про число.** Замер по всем базам машины ⚠ (контроль ИСПР. 11.09 после пере-замера через `find`: файлов `*.db` **448**, с таблицей `request_log` **405**, прочитано **58 886** строк — первый счёт был занижен `glob`-ом): ⛔ **ЧИСЛА ИСПР. 11.09 — ПРЕЖНИЕ БЫЛИ ЗАВЫШЕНЫ В 10.88 РАЗА МОЕЙ ЖЕ ЛОВУШКОЙ (ряд 428): я опубликовал свод обходом диска, не применив к нему собственную норму.** Контроль честный: баз открыто **449**, строк-экземпляров прочитано **58 886**, **УНИКАЛЬНЫХ строк 5 413** (дедуп по идентичности строки, а не по файлу). После дедупа подстановкой оплачено **70 строк**: боевых **65** — `deepseek-v4-flash` → `deepseek-flash` **28 строк, $0.188953** и `local-qwen3-8b` → `huihui_ai/qwen3-abliterated:8b` **37 строк, $0**; фикстур **5** на **$0.424277** (`m-req`→`m-act` 1, `fake-model` 4). ⚠ Прежние «365 · 344 · 21 · $2.049737 · вычесть $5.51» — все одиннадцатикратные, ни одно за результат не принимать — провайдер вернул слаг, которого в каталоге нет, — `deepseek-v4-flash` → `deepseek-flash` (296 строк, $2.049737) и `local-qwen3-8b` → `huihui_ai/qwen3-abliterated:8b` (48 строк, $0). **Сегодня это безвредно:** подстановка падает на ЗАПРОШЕННУЮ модель той же семьи, и пин верен по семье. ⛔ Опасна не подстановка, а то, что о ней **никто не узнаёт**: `PriceForResponse` (`backend/internal/ledger/pricing.go:61`=`func (p *Pricer) PriceForResponse`) пробует `actual`, потом `requested`, потом якорь, и ни одно из ТРЁХ мест вызова не различает, какая ветвь сработала. Комментарий там же охраняет РОВНО ОДНО направление («премиальный ответ не должен биться по дешёвому дефолту»); обратное — когда провайдер маршрутизирует ВНИЗ — не охраняет никто: запрошен `pro`, ответила модель дешевле, счёт идёт по пину `pro`, $3.96 за 1M выходных против $1.20 вендорских у flash = **×3.3 из кармана читателя, молча**. ⇒ лечение двухчастное: завести слаг, который провайдер РЕАЛЬНО возвращает, и сделать срабатывание подстановки ВИДИМЫМ. Носитель работы — пак «падение, которое видно» §4.5 | бэкенд+полигон | **скоро** | вендор-сверка identity слага, затем пере-пин с датой и способом в формулировке; отдельно — наблюдаемость подстановки | критик чисел прогона A, 11.09; подстановка — пере-замер оркестратора 11.09 | | 414 | **ПРИЗНАК ОТКАЗА НЕ ЖИВЁТ В `err`: прогон, где четверть денег купила пустоту, читается через эту колонку как идеально чистый.** Замер 11.09 на живом прогоне: `err` пуст на ВСЕХ 33 строках `request_log`, включая четыре провальные (контроль: строк с `err <> ''` — 0). ⚠ **ИСПР. 11.09 — «единственный носитель» НЕВЕРНО, их ТРИ, и они сходятся точно.** Пере-снято мною по базе прогона (`bk_ROEHZBD46ALFI43E/project.db`, 33 строки): `ok = 0` ровно на четырёх провальных и `1` на остальных 29 · `finish_reason = 'length'` на тех же четырёх · `degraded` (`empty` ×3, `length` ×1). Каждый из трёх, просуммированный по деньгам, даёт **ровно $0.106472** — то есть провал виден тремя независимыми колонками, и `ok` из них самая очевидная. Верна ровно половина прежнего утверждения: пуст именно `err`. ⇒ любой аудит денег или отказов, написанный через `err` — а это первое, к чему потянется рука, — не увидит 25.4 % траты. Родня ряда **376**: там оплаченный обрыв не виден в оценочной паре, здесь провал не виден в колонке ошибок | бэкенд | скоро | отказ обязан быть видим тем же прибором, которым смотрят деньги | критик чисел прогона A, 11.09 | | 415 | ⛔ **ЧЕТВЕРТЬ ДЕНЕГ КНИГИ КУПИЛА ПУСТОТУ, И ПОДНЯТЫЙ ФЛОР ЭТОГО НЕ СНЯЛ — доля БОЛЬШЕ, чем у инцидента, ради которого флор поднимали.** Замер 11.09: 4 вызова из 27 вернулись без пригодного текста и стоили **$0.106472 = 25.4 %** книги; три из них вернули РОВНО 0 знаков ($0.094835 = 22.6 %), четвёртый — выброшенный обрезок. Самый дорогой одиночный вызов прогона ($0.071009, `edit`/`deepseek-v4-pro`) не дал НИЧЕГО. ⚠ Мина задокументирована (размышление съедает `max_tokens`), боевой `pipeline-c1.yaml` ставит на draft `reasoning: "low"` именно против неё — **сработала всё равно: трижды на draft и один раз на edit, где ручка не выставлена вовсе**; а `min_max_tokens: 16000` у `pro` поднят с 8000 ПОСЛЕ прошлого такого инцидента, чья цена записана рядом в комментарии как 15.5 % счёта — здесь один вызов НА ПОДНЯТОМ флоре сжёг 16 000 токенов и вернул ноль, **16.9 % счёта**. ⭐ Лечение в движке ЕСТЬ и сработало 4 раза из 4 (перевыпуск с удвоенным потолком вернул текст) — путь не рвётся, он ДОРОЖАЕТ вдвое. Вторая точка того же явления: на прогоне 08.09 было 32 % | бэкенд | **скоро** | ручка против мины на ВСЕХ платных стадиях + решение, платит ли читатель за выброшенную попытку | критик чисел прогона A, 11.09 | | 416 | **СОГЛАСИЕ НА ПЕРЕ-ОПЛАТУ, ВЫСТАВЛЕННОЕ НА ВЕСЬ БЮДЖЕТ, ПРИ ФАКТИЧЕСКОЙ ПЕРЕ-ПОКУПКЕ В 78 РАЗ МЕНЬШЕ.** Замер 11.09: на резюме после банк-стопа `runs.accept_rebill_micro = 2 241 631` — то есть согласие пере-оплатить ВЕСЬ бюджет прогона, — тогда как фактически пере-куплено $0.028742. Разрыв **78×**; от пере-покупки спасли чекпойнты, а не потолок согласия. ⇒ промахнись хэши промптов (смена провода, `memory_version`, снапшота), и черновая волна была бы куплена заново — с уже стоящим согласием читателя. Родня `D39.196` п.2а (переплата читателя запрещена): здесь запрет не нарушен, но и не охраняем ничем, кроме везения | платформа+бэкенд | скоро | согласие соразмерное тому, что реально может быть пере-куплено | критик чисел прогона A, 11.09 | @@ -341,10 +341,11 @@ | 419 | ⛔⛔ **СТЕММЕР СНИМАЕТ ОДНО ОКОНЧАНИЕ, И ИЗ 18 ПРОМАХОВ ЖИВОГО ПЛАТНОГО ПРОГОНА **11 — ЛОЖНЫЕ**: банковская форма ДОЕХАЛА до читателя в том же юните, склонённая, а пост-проверка её не увидела.** Замерено бэкенд-сессией по-юнитно на копии базы прогона A 11.09 (контроль: 84 показано − 66 последовало = 18, столько же записей в `postcheck_detail`). Механизм один: `TargetStemmer.Stem` снимает РОВНО ОДНО окончание, а двум падежным формам нужны окончания РАЗНОЙ длины ⇒ стеммы выходят разной длины, `SameStem` требует равенства (`backend/internal/lang/stemmer.go:70`=`func (s TargetStemmer) SameStem`), и во всех одиннадцати один стемм — строгий ПРЕФИКС другого с разницей в ОДИН знак («путь»/«пут» · «ветвь»/«ветв» · «крепость»/«крепост» · «злой»/«злог»). Примеры ложных: `正道` «праведный путь» → в тексте «школы праведного пути»; `白家寨` «крепость рода Бай» → «крепости рода Бай» ×2. **Настоящих расхождений 7**, и `家老`/`舅父` из ручного оракула прогона среди них. ⭐ **КЛАСС БЫЛ ПРЕДСКАЗАН, И ЛЕЧЕНИЕ НАЗВАНО В САМОМ ДЕРЕВЕ:** пять из одиннадцати — мягкий знак, исключённый из `decl_suffix` НАМЕРЕННО (`backend/internal/lang/data/target-ru.txt:231`=`the bare SOFT SIGN`, `D39.71`: иначе «Синь»/«Линь» схлопнутся на стеммы «синий»/«линия»), и записка там же говорит — «the soft-sign nominative gap needs seed decl-form enumeration or an **anchor-gated match**, not this global suffix». Пинг стоял; **цена его не была замерена до сегодня**. ⛔ Следствия: (1) число «18 расхождений» завышено в 2.5 раза — эррата 11.09-б; ⚠ **адрес испр. 11.09: числа 18 в теле `D39.247` НЕТ, оно жило в промте пака и в таблице `docs/README.md`, и там же исправлено;** (2) прибор консистентности, переиспользующий банковское равенство, НАСЛЕДУЕТ дыру и врёт примерно в 60 % строк — поэтому пак печатает ДВА числа (по равенству и по якорному послаблению), а разница есть цена стеммера; (3) точность глоссарного чекера **0.067** (ряд 408) — вероятно ТОТ ЖЕ механизм, а не данные сида; проверяется по `fp_ids` ⚠ **11.09: корень шире — ряд 423.** Ненулевые `decl.forms` есть только в рукописных сидах, в машинных выгрузках их НОЛЬ, поэтому на нормальной дорожке продукта одношаговый стеммер — единственное, что работает. | бэкенд | **скоро** | якорное послабление на БОЕВОМ пути `dstFormPresent` — отдельным паком, после замера прибором на размеченном корпусе | пак консистентности, 11.09 | | 420 | ⛔ **`unit_done` ВСТАВЛЕННОЙ ГЛАВЫ НЕ ОБЪЯВЛЯЕТСЯ ВОВСЕ — тихая потеря доставки за швом.** Найдено дизайн-паком перекроя 11.09 при инвентаре чужой стороны: ключ объявления несёт ОРДИНАЛ (`backend/internal/pipeline/events.go`, греп `once_key`), отказ молчалив (греп `outbox`), а `deliveredUnits` считает юнит доставленным. ⇒ при вставке главы читатель не получает объявления о доставке, и никто этого не замечает. **Это не перепокупка, а потеря СОБЫТИЯ**; чинится в движке. ⚠ Единственная настоящая потеря за швом из всего, что дизайн проверил: остальные четыре его подозрения оказались «уже построено» на стороне платформы | бэкенд | скоро | объявление доставки, переживающее вставку главы | дизайн-пак перекроя, 11.09 | | 421 | **ЗАМЕР, РАДИ КОТОРОГО ШЕСТОЙ ВОПРОС СНЯТ С ВЛАДЕЛЬЦА: сколько банк-батчей на боевой книге двигает ТОЛЬКО окно.** Дизайн-пак завёл вопрос о проводе банк-ролей и САМ его снял с владельца доводом «цена меняла знак ТРИЖДЫ — 11 % всегда → ноль → интервал от нуля до всего прохода; число, трижды менявшее знак, владельцу отдавать нельзя». Постановка готова: считать на боевой книге долю батчей, у которых меняется только окно `since_ch`/`until_ch`, и тем закрыть интервал. ⚠ **Ряд заведён 11.09 по находке аудита: и дизайн, и акт `D39.245` объявляли замер «ушедшим в бэклог», а в бэклоге его НЕ БЫЛО** — классический случай «заведено» со слов, без грепа по живому трекеру | бэкенд/полигон | когда-нибудь | доля батчей, двигающих только окно, числом на боевой книге | дизайн-пак перекроя 11.09, заведён аудитом смены | -| 422 | ⛔ **КОЛОНКА, КОТОРОЙ СПРАШИВАЮТ «СКОЛЬКО СЪЕЛО ДУМАНЬЕ», НЕ НЕСЛА ЧИСЛА НИ РАЗУ ЗА ВСЮ ИСТОРИЮ ПРОЕКТА.** Замер 11.09 оркестратором: `request_log.reasoning_tokens > 0` — **0 строк**; контроль рядом, доказывающий, что вопрос задан существующему предмету: ⚠ **контроль ИСПР. 11.09 — мой первый счёт был занижен: `glob` пропустил ~170 баз, пере-снято через `find`** — файлов `*.db` найдено **448**, несут таблицу `request_log` **405**, прочитано **58 886** строк; ноль устоял на БОЛЬШЕМ знаменателе. Колонка объявлена схемой (`backend/internal/store/migrate.go`, блок `CREATE TABLE request_log`) и присутствует во всех. ⇒ **единственная колонка, которой можно доказать «потолок съело рассуждение», структурно молчит**, и её ноль неотличим от «думанья не было». Прямо это и есть слепота в вопросе владельца «мы ждали 249 секунд и заплатили за ничего»: у DeepSeek рассуждение считается ВНУТРИ `completion_tokens` и отдельным полем не приходит, поэтому на провальных вызовах прогона A видно `completion_tokens` 8496 · 8496 · 8496 · 16000 при нуле знаков текста — то есть потолок выкуплен целиком, а чем — не сказано ничем. ⚠ Родня рядов **414** (признак отказа не в той колонке) и **415** (четверть денег за пустоту): все три — про то, что ОТКАЗ и его ПРИЧИНА не доезжают до прибора, которым смотрят деньги | бэкенд | **скоро** | поле, различающее «рассуждение съело потолок» и «рассуждения не было» — из тела ответа провайдера, а не из отсутствующего поля usage; либо явная пометка «провайдер не сообщает» | пере-замер оркестратора 11.09 по базе прогона A | +| 422 | ⛔ **КОЛОНКА, КОТОРОЙ СПРАШИВАЮТ «СКОЛЬКО СЪЕЛО ДУМАНЬЕ», НЕ НЕСЛА ЧИСЛА НИ РАЗУ ЗА ВСЮ ИСТОРИЮ ПРОЕКТА.** Замер 11.09 оркестратором: `request_log.reasoning_tokens > 0` — **0 строк**; контроль рядом, доказывающий, что вопрос задан существующему предмету: ⚠ **контроль ИСПР. 11.09 — мой первый счёт был занижен: `glob` пропустил ~170 баз, пере-снято через `find`** — файлов `*.db` найдено **449**, прочитано **58 886** строк-экземпляров, **УНИКАЛЬНЫХ строк 5 413** (⛔ испр. 11.09: прежний знаменатель сам был умножен копиями в 10.88 раза — ряд **428**; ноль устоял и на честном знаменателе). Колонка объявлена схемой (`backend/internal/store/migrate.go`, блок `CREATE TABLE request_log`) и присутствует во всех. ⇒ **единственная колонка, которой можно доказать «потолок съело рассуждение», структурно молчит**, и её ноль неотличим от «думанья не было». Прямо это и есть слепота в вопросе владельца «мы ждали 249 секунд и заплатили за ничего»: у DeepSeek рассуждение считается ВНУТРИ `completion_tokens` и отдельным полем не приходит, поэтому на провальных вызовах прогона A видно `completion_tokens` 8496 · 8496 · 8496 · 16000 при нуле знаков текста — то есть потолок выкуплен целиком, а чем — не сказано ничем. ⚠ Родня рядов **414** (признак отказа не в той колонке) и **415** (четверть денег за пустоту): все три — про то, что ОТКАЗ и его ПРИЧИНА не доезжают до прибора, которым смотрят деньги | бэкенд | **скоро** | поле, различающее «рассуждение съело потолок» и «рассуждения не было» — из тела ответа провайдера, а не из отсутствующего поля usage; либо явная пометка «провайдер не сообщает» | пере-замер оркестратора 11.09 по базе прогона A | | 423 | ⛔⛔ **МАЙНЕР ЭМИТИТ ТОЛЬКО ТО ПОЛЕ, РАДИ КОТОРОГО ПОСТРОЕН, И КАЖДЫЙ МЕХАНИЗМ НИЖЕ ПО ТЕЧЕНИЮ, КОТОРОМУ НУЖНЫ ДАННЫЕ БОГАЧЕ, ТИХО ДЕГРАДИРУЕТ. Три открытых ряда оказались ОДНИМ классом.** Замер оркестратора 11.09 (контроль: прибор распарсил **47** yaml-файлов с непустым `terms:`): ненулевые `decl.forms` есть ТОЛЬКО в файлах, написанных человеком — `guzhenren-seed-v2.yaml` 42 терма из 58 · `guzhenren-seed.yaml` 35 из 49 · `rerun2` 41 из 57; **во ВСЕХ машинных выгрузках — ноль**: 0 из 142 · 0 из 102 (шесть раз) · 0 из 83 · 0 из 76 · 0 из 74 · 0 из 69 (банк платного прогона A) · 0 из 67 · 0 из 61 · 0 из 53. ⇒ **на книге без рукописного сида — то есть на нормальной дорожке продукта — пост-проверке нечем опереться, кроме глобального одношагового стеммера**, и это ровно тот механизм, который ряд **419** замерил как дающий 11 ложных тревог из 18. Три инстанса одного класса: `decl.forms` (`internal/seed/seed.go:87`=`type Decl struct`, потребитель `membank/memory.go:343`=`Parse decl forms for the post-check`) · профили голоса (ряд **410**: `voices:` пуст во ВСЕХ 22 машинных выгрузках и отсутствует во ВСЕХ 22 рукописных сидах) · формы глагольных и многословных термов (ряд **408**). ⭐ **Ценность ряда в том, что он снимает три отдельные «доработки данных» и ставит один вопрос: что банк обязан отдавать, кроме пары «исходник → передача», чтобы механизмы ниже работали не вырожденно.** ⚠ Это НЕ заказ «научить майнер всему»: часть полей модель предложить не может в принципе (склонение — да, голос — спорно), и разделение «что майнится · что сеется человеком · что вычисляется из языка» и есть предмет. ⛔ Пока ряд открыт, любой замер точности пост-проверки на РУКОПИСНОМ корпусе меряет исключение, а не правило — этим 11.09 ошибся оркестратор, решая порядок колонок прибора консистентности | бэкенд | **скоро** | разделение «майнится · сеется · выводится из языка» + носитель того, чего майнер не даёт | пере-замер оркестратора 11.09 по числу зоны `textmachine-c9` | -| 424 | **ЧЕТЫРНАДЦАТЬ РЯДОВ ТРЕКЕРА РЕНДЕРЯТСЯ С ЛИШНИМИ КОЛОНКАМИ — неэкранированный `\|` внутри ячейки, обычно в код-спане вида `auto\|draft\|approved`.** Замер 11.09 структурной проверкой по всей таблице (контроль: рядов прочитано **298**, сломанных **14**): 163 · 182 · 248 · 127 · 253 · 279 · 306 · 311 · 320 · 346 · 361 · 378 · 389 · 407. Лечение — `\|` в ячейке; работа механическая. ⭐ **Ряд заведён не ради косметики, а потому что гейт этого НЕ ВИДЕЛ, и слепота стоила инцидента:** проверка формы в `docs/scripts/counts.py` ловила только «колонок МЕНЬШЕ ожидаемого», а «больше» и «текст за последним разделителем» молчали — и ряд **406** прожил от создания до 11.09 с **1044 знаками текста ВНЕ таблицы**, при этом счётчики сходились (они читают ячейки с конца и попадали в нужные) и гейт был зелён. Проверка сделана симметричной тем же днём, эти 14 внесены в `SHAPE_GRANDFATHERED` по конвенции файла «гейт рождается зелёным на известном долге и краснеет на следующем»; три посадки на копии подтвердили, что обе новые половины краснеют ПО ТЕКСТУ, а дедовщина молчит. ⇒ закрытие ряда = экранировать 14 ячеек и вынести их из списка | оркестратор | когда-нибудь | экранирование `\|` в четырнадцати ячейках и пустой `SHAPE_GRANDFATHERED` | структурная проверка оркестратора 11.09 | +| 424 | **ТРИНАДЦАТЬ РЯДОВ ТРЕКЕРА РЕНДЕРЯТСЯ С ЛИШНИМИ КОЛОНКАМИ — неэкранированный `\|` внутри ячейки, обычно в код-спане вида `auto\|draft\|approved`.** Замер 11.09 ТЕМ ЖЕ расщепителем, что у гейта (контроль: рядов прочитано **303**, целых **290**, сломанных **13**): 163 · 182 · 248 · 127 · 279 · 306 · 311 · 320 · 346 · 361 · 378 · 389 · 407. ⛔ **Первая редакция называла ЧЕТЫРНАДЦАТЬ и включала ряд 253 — это была ошибка ПРИБОРА, а не находка: я считал разделители наивно, а 253 их ЭКРАНИРУЕТ, и расщепитель гейта видит его целым.** Хуже: ошибка уехала В САМ ГЕЙТ — 253 попал в `SHAPE_GRANDFATHERED` и ослепил проверку на неcломанном ряде навсегда; снят 11.09. ⇒ **урок дороже ряда: контроль снимается ТЕМ ЖЕ прибором, которым судит гейт, иначе дедовщина консервирует не долг, а мой промах.** Лечение — `\|` в ячейке; работа механическая. ⭐ **Ряд заведён не ради косметики, а потому что гейт этого НЕ ВИДЕЛ, и слепота стоила инцидента:** проверка формы в `docs/scripts/counts.py` ловила только «колонок МЕНЬШЕ ожидаемого», а «больше» и «текст за последним разделителем» молчали — и ряд **406** прожил от создания до 11.09 с **1044 знаками текста ВНЕ таблицы**, при этом счётчики сходились (они читают ячейки с конца и попадали в нужные) и гейт был зелён. Проверка сделана симметричной тем же днём, эти 14 внесены в `SHAPE_GRANDFATHERED` по конвенции файла «гейт рождается зелёным на известном долге и краснеет на следующем»; три посадки на копии подтвердили, что обе новые половины краснеют ПО ТЕКСТУ, а дедовщина молчит. ⇒ закрытие ряда = экранировать 14 ячеек и вынести их из списка | оркестратор | когда-нибудь | экранирование `\|` в четырнадцати ячейках и пустой `SHAPE_GRANDFATHERED` | структурная проверка оркестратора 11.09 | | 425 | **ПРИБОР КОНСИСТЕНТНОСТИ СЛЕП ПО ПОСТРОЕНИЮ В ШЕСТИ МЕСТАХ, и ни одно не чинится матчером.** Названо зоной 11.09 на прямой вопрос «что ты знаешь и не сказала» — до вопроса была названа ОДНА. **(1)** передача, СОДЕРЖАЩАЯ форму банка целиком, и есть эта форма (`开窍大典`) — единственное расхождение с ручным оракулом, где прибор слеп структурно; **(2)** омонимы по `sense`: одно вхождение засчитывается КАЖДОМУ ряду с тем же ключом, и обе строки полисемичного терма покрытыми быть не могут (латентно: 69 различных `src` на 69 рядов); **(3)** ⛔ общеупотребительная передача вдали от своего термина маскирует настоящее отсутствие — `魔道` даёт `fired=1` при счёте 3; **сдвиг ОДНОСТОРОННИЙ, в сторону благополучия ⇒ `I2` есть НИЖНЯЯ граница, а не оценка**, и число уже печатается строкой «terms found MORE often than their key fired» (на прогоне A 9 и 7); **(4)** гранулярность — ЮНИТ, а не вхождение: «форма на месте срабатывания» требует выравнивания исходника с целью; **(5)** термин, которого в банке НЕТ, невидим вовсе — молчание неотличимо от успеха; **(6)** вторая форма НЕ НАЗЫВАЕТСЯ никогда: I1 ловится отсутствием банковской формы, а не узнаванием того, что стоит вместо неё. ⇒ **(1) и (6) закрываются ОДНИМ заказом — каналом `variants` в БД**; (3) закрыто числом рядом с `I2` | бэкенд | скоро | канал `variants` закрывает (1) и (6); прочее — объявленные свойства, пере-открывать замером | зона пака консистентности 11.09, секция «где прибор слеп и я это знаю» | | 426 | **ГРАНИЦЫ НОРМАЛИЗАЦИИ И РАВЕНСТВА — три, все с числом.** **(1)** граница АБЗАЦА не видна: `NormalizeTargetForm` сворачивает любой пробельный ряд в один пробел, поэтому разрыв абзаца без конечной пунктуации неотличим от пробела; граница ПРЕДЛОЖЕНИЯ закрыта и пинована, а видеть абзац значит завести ВТОРОЙ нормализатор, расходящийся с пост-проверкой. **(2)** строгая колонка не в точности равна `dstFormPresent` в ОБЕ стороны — слова против рун: пунктуация внутри формы (**23 расхождения на 30 000 троек**) и форма без букв; недостижимо на банке без `decl`-форм, то есть на ЛЮБОМ машинном (ряд **423**). **(3)** ⛔ **точность самого отношения `NearStems` ≈ 0.57** — 17 из 30 равномерной выборки принятых пар (`рода~родной`, `гор~горная`, `так~также` — разные леммы) ⇒ **работает не отношение, а ограждения** (якорь · многословное окно · границы предложения), и их эффективность замерена на ОДНОЙ книге; названный отказ — слово банковской передачи оказывается соседом ДРУГОГО слова в той же позиции окна, и колонка врёт в сторону сокрытия | бэкенд | скоро | (3) — вторая книга либо размеченные пары лемм; (1) и (2) — объявленные свойства | зона пака консистентности 11.09 | | 427 | ⛔ **СТУПЕНЬ ТОЧНОСТИ ПРИБОРА НЕ ЗАЩИЩЕНА НИ НА ОДНОЙ МАШИНЕ, КРОМЕ ЭТОЙ.** Корпусные пины (`TestK6*`, `TestTheInstrumentAgainstTheColdRunOracle`) держатся только там, где есть дерево `books/`; здесь они идут и несущие в гейте, но **до первого гейта на другой машине или в CI ступень точности не защищена ничем**. ⚠ Различать надо две ступени, и первая цела: **механизм первичного вердикта защищён ГЕРМЕТИЧНО** — пять синтетических пинов краснеют без дерева книг (проверено посадкой четырёх мутаций дважды: «4 mutation(s) run, 0 unexpected»). Корпусные защищают ТОЧНОСТЬ, и это вторая ступень. Смягчение уже построено зоной: `backend/Makefile` цель `mutations` экспортирует абсолютные пути к корпусу, `battery-stand` форсирует `TM_CHECKER_LABELS=1` — отсутствие данных там ПАДАЕТ, а не скипает. ⇒ остаток ряда: что делает CI, у которого дерева книг нет по построению | бэкенд+оркестратор | скоро | решение по корпусу в CI: везти, генерировать или объявить ступень машино-зависимой | зона пака консистентности 11.09, проход старшего коллеги исполнением | -| 428 | ⛔ **ЧЕТВЁРТАЯ ЛОВУШКА ДЛЯ СЧИТАЮЩИХ ДЕНЬГИ, и она умножает счёт на число КОПИЙ базы.** Замер оркестратора 11.09 при приёмке (контроль: `find` дал **449** файлов `*.db`, таблицу `spend` несут **406**, строк `spend` — **295**, различных дат — 18): сумма `committed_usd` по всем базам машины за 11.09 даёт **$4.354443 на 13 строках**, тогда как настоящая трата дня — **$0.419423 ОДИН раз**. Разница — не ошибка движка: таблица `spend` ключуется `(book_id, date)` и переезжает вместе с файлом, а рабочая сессия сделала девять копий базы прогона (`runA`, `runA-frozen`, `dbcopy`, обзорные копии, пред-миграционные бэкапы) — **одна и та же строка сосчиталась десять раз**. Плюс промежуточный бэкап на $0.16021 добавил одиннадцатый счёт того же прогона в другой момент времени. ⇒ **любой денежный свод, собранный обходом файлов по диску, завышает трату кратно числу копий**, и это первое, к чему потянется рука при вопросе «сколько мы потратили за день». ⚠ Родня трёх ловушек акта `D39.247` п.5 (`run_attempts.spend_micro_usd` накопленная · `err` пуст на провалах · `chunk_status` недобирает терминологию) — у всех один класс: **прибор денег отвечает на вопрос, которого ему не задавали.** Лечение — не код, а норма свода: деньги считаются по УНИКАЛЬНОМУ `(book_id, date)` либо по одной авторитетной базе, и рядом печатается, сколько файлов прибор обошёл | оркестратор | скоро | норма денежного свода в ролевом промте + дедупликация по `(book_id, date)` | приёмка пака консистентности, 11.09 | +| 428 | ⛔ **ЧЕТВЁРТАЯ ЛОВУШКА ДЛЯ СЧИТАЮЩИХ ДЕНЬГИ, и она умножает счёт на число КОПИЙ базы.** Замер оркестратора 11.09 при приёмке (контроль: `find` дал **449** файлов `*.db`, таблицу `spend` несут **406**, строк `spend` — **295**, различных дат — 18): сумма `committed_usd` по всем базам машины за 11.09 даёт **$4.354443 на 13 строках**, тогда как настоящая трата дня — **$0.419423 ОДИН раз**. Разница — не ошибка движка: таблица `spend` ключуется `(book_id, date)` и переезжает вместе с файлом, а рабочая сессия сделала девять копий базы прогона (`runA`, `runA-frozen`, `dbcopy`, обзорные копии, пред-миграционные бэкапы) — **одна и та же строка сосчиталась десять раз**. Плюс промежуточный бэкап на $0.16021 добавил одиннадцатый счёт того же прогона в другой момент времени. ⛔ **И тем же множителем больна ВТОРАЯ таблица, что я обнаружил только пере-замером по наводке аудита: `request_log` — 58 886 строк-экземпляров на 449 базах суть **5 413 УНИКАЛЬНЫХ**, множитель **10.88×**.** Я опубликовал по нему числа подстановки цены (ряд 413) и контроль ряда 422, не применив к ним собственную норму из ЭТОГО ряда — между заведением нормы и её нарушением прошёл час. ⇒ **любой денежный свод, собранный обходом файлов по диску, завышает трату кратно числу копий**, и это первое, к чему потянется рука при вопросе «сколько мы потратили за день». ⚠ Родня трёх ловушек акта `D39.247` п.5 (`run_attempts.spend_micro_usd` накопленная · `err` пуст на провалах · `chunk_status` недобирает терминологию) — у всех один класс: **прибор денег отвечает на вопрос, которого ему не задавали.** Лечение — не код, а норма свода: деньги считаются по УНИКАЛЬНОМУ `(book_id, date)` либо по одной авторитетной базе, и рядом печатается, сколько файлов прибор обошёл | оркестратор | скоро | норма денежного свода в ролевом промте + дедупликация по `(book_id, date)` | приёмка пака консистентности, 11.09 | +| 429 | **БОЕВОЙ КОНФИГ НЕСЁТ ОТОЗВАННЫЙ ВЕНДОРСКИЙ КЛЕЙМ, И ЧИТАТЕЛЬ ЕМУ ВЕРИТ.** `backend/configs/pipeline-c1.yaml:86`=`v4-pro maps low` дословно: «v4-pro maps low→high, effective effort unchanged». Это было верно до 30.08 и **ОТОЗВАНО**: вендор сменил маппинг (`docs/experiments/00-provider-quirks.md` §3а — таблица теперь ОДНА на обе модели, `low→low`), и поведенческая проба полигона 30.08 за $0.038276 показала, что `low` до `pro` ДОХОДИТ. ⇒ комментарий в дереве утверждает ровно обратное живой правде, и стоит он в том самом файле, который промты велят читать. ⚠ Цена не гипотетическая: на этом клейме строилась оценка «ручки у редактора нет вовсе», и она уже уводила решение. ⛔ **Класс шире одной строки: вендорский факт, вмороженный в комментарий, протухает молча — у комментария нет ни даты, ни гейта, ни владельца.** Лечение узкое — привести строку в соответствие; лечение широкое — правило, по которому вендорский факт в коде несёт дату снятия и указатель на квирки, а не живёт вечно | бэкенд | скоро | правка строки 86 + правило «вендорский факт в комментарии несёт дату и адрес» | аудит смены 11.09 | diff --git a/docs/scripts/counts.py b/docs/scripts/counts.py index 0fc5c2e6..4437d6a4 100644 --- a/docs/scripts/counts.py +++ b/docs/scripts/counts.py @@ -172,7 +172,9 @@ def weight_of(line: str) -> str: # Ряды, у которых лишние колонки — ЗНАЕМЫЙ долг: неэкранированный `|` внутри ячейки (обычно в # код-спане вида `auto|draft|approved`). Та же конвенция, что у WEIGHT_GRANDFATHERED: гейт рождается # зелёным на известном и краснеет на следующем. Долг числится строкой бэклога 424. -SHAPE_GRANDFATHERED = {"163", "182", "248", "127", "253", "279", "306", "311", +# ⚠ 253 СНЯТ 11.09: он в этот список попал по ошибке — я считал разделители наивно, а этот ряд их +# ЭКРАНИРУЕТ, и расщепитель гейта видел его целым. Дедовщина на неcломанном ряде слепит гейт там навсегда. +SHAPE_GRANDFATHERED = {"163", "182", "248", "127", "279", "306", "311", "320", "346", "361", "378", "389", "407"}