From 2564a8a7dd55c54f681595e6b7e2dbdb3921988e Mon Sep 17 00:00:00 2001 From: heaven Date: Sun, 6 Sep 2026 21:38:38 +0300 Subject: [PATCH] Move the single project backlog into its own file so the journal keeps only state, and repoint the counters, the hook and every live pointer to it --- docs/BACKEND_CONSISTENCY_SESSION_PROMPT.md | 2 +- docs/BACKLOG.md | 277 ++++++++++++++++++ docs/PLATFORM_MONEY_TRUTH_SESSION_PROMPT.md | 2 +- ...OLYGON_INSTRUMENT_REPAIR_SESSION_PROMPT.md | 2 +- docs/PROGRESS.md | 273 +---------------- docs/README.md | 5 +- docs/STACK.md | 2 +- docs/architecture/01-decisions.md | 2 +- docs/architecture/03-implementation-notes.md | 2 +- docs/architecture/05-decisions-index.md | 5 +- docs/architecture/05-decisions-log.md | 49 +++- docs/architecture/06-memory-risk-registry.md | 2 +- docs/architecture/13-tech-debt-anchors.md | 6 +- docs/architecture/15-money-path.md | 6 +- docs/glossary.md | 2 +- docs/scripts/counts.py | 18 +- docs/scripts/githooks/pre-commit | 5 +- 17 files changed, 362 insertions(+), 298 deletions(-) create mode 100644 docs/BACKLOG.md diff --git a/docs/BACKEND_CONSISTENCY_SESSION_PROMPT.md b/docs/BACKEND_CONSISTENCY_SESSION_PROMPT.md index e443bcd7..24bea29f 100644 --- a/docs/BACKEND_CONSISTENCY_SESSION_PROMPT.md +++ b/docs/BACKEND_CONSISTENCY_SESSION_PROMPT.md @@ -21,7 +21,7 @@ ## 3. Карта чтения — ЗАКОН, дальше только по её ссылкам 1. `CLAUDE.md` — цели владельца и гардрейлы. -2. Строки бэклога **267**, **318**, **320** (`docs/PROGRESS.md`, греп `^| N |`). +2. Строки бэклога **267**, **318**, **320** (`docs/BACKLOG.md`, греп `^| N |`). 3. `backend/README.md` — механика движка. 4. `docs/architecture/03-implementation-notes.md` — через баннер. 5. `docs/architecture/12-go-style-notes.md` — только больные места. diff --git a/docs/BACKLOG.md b/docs/BACKLOG.md new file mode 100644 index 00000000..a18b0577 --- /dev/null +++ b/docs/BACKLOG.md @@ -0,0 +1,277 @@ +# ЕДИНЫЙ БЭКЛОГ — движок · полигон · доки · процесс + +> **Единственный трекер проекта.** Здесь живут строки, на которые доки, промты и 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). Здесь только долг и его диспозиции. +> - **СЧЁТ ОЧЕРЕДИ на 05.09 (скриптом по таблице — `python3 docs/scripts/counts.py`; обновлять при каждом лендинге):** всего **240** строк · зона бэкенд **113** строго / **158** широко (⚠ колонки счётчик читает С КОНЦА — испр. D39.116) · **блокеров очереди 0** (236 закрыта D39.175), платные прогоны разблокированы · «скоро» **106** (перечень — грепом по таблице, рукописный список снят 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; правки — только через оркестратора) + +Закрытые строки здесь НЕ хранятся — они уходят в D-лог с номером решения. **ID строки стабилен навсегда** (не перенумеровывается и не переиспользуется — на «строку N» ссылаются доки и промты, D39.80). Вес: «блокер-очереди» = мешает текущему шагу · «скоро» = ближайшие 1–2 касания · «когда-нибудь» = записано, не потеряно. Длинная строка начинается жирным лидом — таблица сканируется по лидам; «диспозиция сверху, археология вниз», ячейка >800 байт — кандидат на выселение в `architecture/13-tech-debt-anchors.md` (D39.125 п.3/D39.126). ⚠ **Счёт очереди — НИЖНЯЯ граница долга, а не потолок:** трекер содержит только замеченное, и 02.08 дважды за $0 свежие глаза вытащили из кода дефекты, которых в нём не было (релей фронта → строки 99/100/102; приёмочное ревью → третий шов в 104 и честность в 105); ленту ✅ шапки читать как «долга нет» неверно (D39.89). **Зонные бэклоги (решение владельца 02.08, D39.84):** фронт и платформа ведут СВОИ бэклоги (`frontend/docs/BACKLOG.md` · `platform/BACKLOG.md`) — их строки сюда НЕ заходят; здесь движок/полигон/доки, включая движковые стыки фронта (зона «бэкенд», как 99–102); строки 96/97 переехали в платформенный (П-1/П-2), надгробия-указатели сохранены. + +| ID | Хвост (одной фразой) | Зона | Вес | Чем закрывается | Источник | +|---|---|---|---|---|---| +| **— ВИСИТ НА ВЛАДЕЛЬЦЕ —** | | | | | | +| 2 | Четыре вопроса границы «алгоритмического идеала» (Annotator · семантический судья · ja→ru §B5 · ru-target до/после) | владелец | скоро (гейт «добора идеала» перед МАСШТАБОМ) | отдельное решение | D39.33, D39.38 | +| 4 | **Ре-чек ToS по триггерам** — первый ИСПОЛНЕН 31.07, дельт вердиктов нет (D39.57); предмет Google-мониторинга перевешен на цепочку договора (PUP · Additional ToS · Google APIs ToS); следующие: квартал 25.10.2026 · первая лейблованная книга · любая правка `accepts_labels` | владелец/полигон | скоро (следующий триггер 25.10.2026) | отдельное решение (правило) | D39.32, D39.57 | +| 5 | **Арбитраж банка: замер ИСПОЛНЕН и ПРИНЯТ (research/24, D39.102).** Закрыто классом: равноправный совет · кросс-модельные веса уверенности · self-consistency · селекция из вариантов · отказ-сигнал ⟦TM-NO-DST⟧; Q2 отвечен — семейства не окупаются (C3−SC=+3 и все три добычи = один кластер; glm-соло 25/45 > совет 23/45). **ОСТАТОК СТРОКИ:** рецензент-другого-семейства ТОЛЬКО на спорных КЛАСТЕРАХ (слот при ре-пробе 74), роутинг целыми family/series-юнитами (G4), эмиссия рецензента — та же draft/⟨проверить⟩. История захода — D39.89/90/101/102 | полигон/ресёрч | **ОСТАТОК ГЕЙЧЕН ре-пробой 74** (D39.102 п.2) | замер (остаток) → решение | D39.89, **D39.102** | +| 6 | **Строка Gemini в `accepts_labels`** — ждёт слова владельца о подписи интерпретации сужения как разрешения; ре-чек 31.07 понизил приоритет: подпись даёт ПРАВО, но не судью 18+ (фильтр неконфигурируем D22.6 + обход запрещён договором) — возвращаться при вопросе, требующем именно права | владелец | когда-нибудь | отдельное решение | D39.32, D39.57 | +| 7 | Q2 «редактор под `sexually-explicit`» (grok-4.3 интерим · glm-5 после сверки ToS Z.AI · mistral вон) | владелец | когда-нибудь (перед первой explicit-книгой) | отдельное решение | D39.27 п.7 | +| 8 | D22.7 пер-чанковый L3-скрин — несня­тое предусловие первой erotica-книги в проде, отдельный гейт | владелец | когда-нибудь | отдельное решение | D22.7, CURRENT-STATE (оркестратор) | +| 9 | Промпт-слой под лейблом: лейбл не доезжает до промпта — должны ли переводчик/редактор знать о свойстве контента | владелец | когда-нибудь | отдельное решение | CURRENT-STATE (владелец, из пака-17) | +| 10 | Дата создания аккаунта OpenAI (низкий приоритет, OpenAI вне цепочки) + применимость OpenAI Sharing & publication policy 2022 (quirks:128) | владелец | когда-нибудь | отдельное решение | D39.32 | +| 11 | Флип coverage-гейта (`enabled:false`, D12-Q4) — за подписью владельца ; при флипе решить судьбу v1.1 quote-absorption (D12-Q1, Python-first лок-степ) | владелец | когда-нибудь | отдельное решение | D39.34(2) | +| 12 | **`postcheck_gate` в hard-gate** — требует пере-замера recall (recall чекеров измерен и низок); ⚠ «fn=0» демоции #10 класс-вакуумен на labels (ноль одно-Han-позитивов, D39.78) — пере-замер обязан добрать одно-Han-позитивы, на «fn=0» не опираться; одно-Han-класс при gate-on вне гейта (Unverified+Demoted); тем же решением строится HARD-value-детектор 成/万 (Q3 §6 — честный hard-gate требует value-чека; либо раньше при ненулевом потоке value-дефектов добора, D39.79; **$0-прототип получен эксп-21: `battery.check_numbers`, симметричный разбор, синтетика 16/16 — D39.117**) · recall существующих гейтов печатал арм C эксп-21 на контаминированном срезе (D39.108/D39.117) | владелец | скоро (⚠ испр. 05.09: `D39.205` п.4 сделал эту строку ПРЕДУСЛОВИЕМ решения владельца по гейту глоссария — прежний вес «когда-нибудь» противоречил ратифицированному; порядок работ — строка 295) (после фазы 2) | отдельное решение | D39.34(2), D24.4+D28.1, D39.39, D39.78, D39.79 | +| 13 | **Включение платной петли ремонта + per-class исходы ремонта** (схемное решение принимается вместе) — вернуться при расширении классов детекторов и ненулевом остатке; ⚠ при включении: репэйр-гард №5 после #10 слеп на одно-Han-дифференциал (демоция в обоих прогонах ⇒ 0>0 — репэйр, стёрший верно отрендеренный одно-Han-термин, не ветируется; D39.78-ревью) | владелец | когда-нибудь | отдельное решение | D39.38, D39.39(а), D39.78, CURRENT-STATE | +| 13б | **`speech-cue.txt` zh НЕ шипить до замера голос-флаггера; замера НЕТ (D39.86) — оси не считались НИ РАЗУ.** ⚠ **Причина ПЕРЕ-НАЗВАНА: прежний довод «редакторская волна не гонялась» ПРОТУХ 31.08** (холодный прогон `coldrun-v16` её гонял и оплатил — строка 16); живой блокер — ПУСТОЙ РЕЕСТР профилей, см. ниже. ⚠ **ГЕЙТ ПЕРЕ-СНЯТ 05.09:** прежний требовал «подписанных профилей (строка 24)», а подпись владелец снял (D39.198 п.5) — значит гейтом остаётся ОДНО: первый прогон добора идеала С редакторской волной. ⛔ **Но снятие подписи открыло дыру, и её надо закрыть раньше стройки:** реестр `voices:`/`addresses:` физически заполняет только подпись (`backend/internal/config/seed.go`, греп `no miner emits them`), и если подписи нет — заполняет НИКТО. Вопрос вынесен строкой 24. ⚠ Сам гейт в схеме ЕСТЬ (`internal/config/pipeline.go` `VoiceGate`, пак-19/D39.55). ⚠ `rules=` в отчёте = «гейт СКОНФИГУРИРОВАН», не «отработал» — до фикса читать по знаменателям `replies=` — носитель **292** (испр. 05.09: 105 закрыта D39.200 только половиной (а), знаменатели уехали в 292). Археология дословно — `architecture/13-tech-debt-anchors.md` §Б-13б. ⚠ **ПОПРАВКА 23.08 (№19):** заполнить `voices:`/`addresses:` может только подпись владельца (`internal/seed/seed.go:23`=`Voices and Addresses are the two D21 record types` — «no miner emits them»), а при пустом реестре `RunVoiceChecks` выходит на `!reg.HasData()` ДО ВСЕХ осей, поэтому нулями отдаются и оси, и знаменатели — «ноль флагов» неотличим от «оси не считались». ⚠ Отдельно: `gates.voice` отсутствует в `backend/configs/`, НО в конфигах реальных прогонов (вне git) он ВКЛЮЧЁН — `~/books/gu-zhenren/coldrun-a/pipeline.yaml:68` и `coldrun-b:71`, `enabled: true`; дыра не «оператор забыл включить», а «шаблоны репозитория гейт не несут» | владелец | отложено-до-замера | первый прогон добора идеала С РЕДАКТОРСКОЙ ВОЛНОЙ (оси голоса, строка 24) → отдельное решение | D39.56, PACK19_BUILD §7.2, чат 31.07, D39.86 | +| 14 | **Четыре data-инженерных флага фазы-2 общности, каждый с рекомендованным дизайном** (§5 отчёта): ё-фолд → target-данные (`char_fold`; смена сигнатуры core-примитива через вердикт-несущий банк, сдвиг `memory_version`) · segmentation-фолбэк громким (ломает контракт corridor-фолбэка `pipeline.go:839-848` + голден-фикстура на нём; лечение — объявить блок в голден-yaml) · `Fertility` per-script map (калибровка ждёт боевого токенизатора) · `source-encoding.txt` + Go-реестр декодеров | владелец | когда-нибудь (следующий пак общности) | отдельное решение | D39.64, GENERALITY_PHASE2 §5.1–5.4 | +| 86 | **Мелкие открытые решения одним списком** (свип D39.66): echo-семантика дропнутого c-lite-члена (D39.18 — оставить pre-c-lite?) · magnitude-кап тяжёлой CJK-утечки (D38.3 п.4в; сейчас strip+flag) | владелец | когда-нибудь | отдельные решения | D39.66, D39.69(feed_cap закрыт §1) | +| **— ХВОСТЫ ХОЛОДНОГО ПРОГОНА (исполнен достаточно, D39.58; Р7 владельца) —** | | | | | | +| 16 | **Полная цена холодного старта — ЖИВОЙ ОСТАТОК ОДИН: цена ДОВЕДЁННОЙ ДО КОНЦА книги не измерена.** Холодный прогон `coldrun-v16` 31.08 отдал 3 юнита из 14 и остановлен снапшот-гардом. ⚠ **Довод «редакторская волна не гонялась» ПРОТУХ 31.08** (испр. 02.09): она гонялась и оплачена — 4 чекпойнта `edit/editor/deepseek-v4-pro` на $0.214865; не мерена именно ПОЛНАЯ цепь одним заходом до конца книги. **Числа ДО редактуры — база прогона `~/books/gu-zhenren/coldrun-b/reprobe/bank-low/guzhenren-bank-low.db`** (10 глав, `low` на черновике И на бэнк-ролях; арифметика снята 23.08 №19): вся ДРАФТ-стадия $0.031639 (flash $0.021289 + pro $0.010350) · терминолог $0.005750 · классификатор $0.007706 · **весь заход $0.045095**, слагаемые дают именно его. ⚠ Числа в ИЮЛЬСКИХ деньгах — множитель пере-пина DeepSeek 4.47 (D39.179 п.1), сегодня тот же заход $0.2017. ⚠ Фаза C `coldrun-b` закрыта владельцем как неуспешная (02.08, D39.90), её деньги не тронуты ($0). Строка держит и оси голоса (13б/24) | бэкенд | когда-нибудь (гейт: первый ЗАВЕРШЁННЫЙ прогон) | добор идеала | D39.58, **D39.90** | +| 18 | **Эмиссия головы 蛊**: сид-половина = чек-лист (определяющий терм книги сидится `allow_short`, D39.50); эмиссия-КАНАЛ демотирован до ИЗМЕР-ГЕЙТА (Q7): полигон-замер «меняет ли эмиссия головы рендер композитов» — строить ТОЛЬКО по эффекту и ПОСЛЕ #10 (однознаковый пост-чек чинится чекер-паком); перед стройкой резолвить K-гейт и KWIC-грязь одиночной головы | полигон → бэкенд | скоро (санкция Q7 D39.70 — после #10, очередью с ре-пробой) | полигон-замер → решение | D39.58, D39.60, D39.69 | +| 24 | ⚠ **ГЕЙТОМ БОЛЬШЕ НЕ ЯВЛЯЕТСЯ — испр. 05.09 (D39.198 п.5):** прежняя редакция держала «профили голоса НЕ ПОДПИСАНЫ» как предусловие, а владелец подписи снял («зачем мне это подписывать») и вытаскивать черновик из книжного дерева не надо. Голос — приоритет №3 из трёх, то есть работа, а не блокер. **Остаток: авто-режим флага** (проект Б не гонялся) · оси голоса A–D · слот инъекции голоса и решение gates.voice при ненулевых осях (D39.55/D21 п.2) · слой-2 voice не строим до доказательства слоя-1 · сверить until_ch 白凝冰 при курации сида (D19.3в). ⚠ **ОТКРЫТЫЙ ВОПРОС, РОЖДЁННЫЙ СНЯТИЕМ ПОДПИСИ:** реестр профилей (`voices:`/`addresses:` сида) сегодня физически заполняет ТОЛЬКО подпись владельца — `backend/internal/config/seed.go`, греп `no miner emits them`. Если подписи нет, ЗАПОЛНЯЕТ КТО? Ответ нужен раньше стройки: без него строка 13б навсегда «отложено до замера» | бэкенд | когда-нибудь | работа третьего приоритета | D39.40, D39.58 | +| **— ТЕКУЩАЯ ОЧЕРЕДЬ (D39.59) —** | | | | | | +| 78 | **Леджер денег = НИЖНЯЯ граница**: «2xx body decode failed (call IS billed)» — провайдер списал, исходная попытка в `request_log` НЕ попадает (≤$0.009/сессия); дизайн фикса ГОТОВ (GENERALITY_PHASE2 §5.6: `BilledDecodeFails` + per-billed-attempt settle с `Estimated=true`), но это money/ledger-путь — не $0-хастл. **Живое число (D39.86):** на ре-пробе 74 — 3 таких вызова на 14, неизвестность **$0.015111** при леджере $0.114378 (13% захода); движок засеттлил оценку и честно напечатал `estimated-cost rows: 3` ⇒ канал ВИДЕН, но `decode_error` при этом ещё и терминален (не retryable, не escalatable) — 3 из 7 терминальных флагов пробы A | бэкенд | когда-нибудь (money-паком) | отдельное решение (дизайн §5.6) | D39.61, D39.64, D39.86 | +| 79 | **Граница ПЛОТНОСТИ письма для серий**: `enabled` через Go-константу `cjkScriptNames` — новый плотный скрипт требует правки Go (head-finality уже в данных script-series.txt; пре-существующая граница, D39.75). Первые два компонента строки (isCyrLetter→`isTargetWordLetter` · magnitude `SourceScripts`-гейт) исполнены пакетом-чекеров, D39.78 | бэкенд | когда-нибудь | следующий пак общности / касание чекеров | D39.64, D39.78 | +| 90 | **Ф2-кандидаты 02-mvp-плана без носителя** (свип-хвост, D39.73): CometKiwi/T-index метрики судьи · Batch API судьи (экономия) · llama-server-интеграция локали · стриминг — взять/закрыть при пилот-препе; + H16 самоулучшение (V3-п.2, ПТ-26): дизайн петли по данным судьи — тем же препом | полигон/бэкенд | когда-нибудь (Ф2.5) | пилот-преп-промт (с 85) | 02-mvp-plan, D39.66, D39.73, D39.80 | +| **— НАХОДКИ СВИПА ПОЛНОТЫ (D39.66: 951 обязательство проверено, потери возвращены в трекер) —** | | | | | | +| 80 | **Резюме-слой памяти** — проза-суммарайзер ЗАКРЫТ (D39.69); строка = ГЕЙТ ПИЛОТА Ф2.5: первый деливерабл пилота — «допускает ли автономная нарратив-состояние-строка ДЕТЕРМИНИРОВАННЫЙ верификатор (source-anchored) — или это D1-компаундинг со схемой»; не-покрытые классы (source-anchored reveal · арк-колбэки без ключа) реальны, но не измерены как дефект | Ф2.5 (Q3 подтверждён D39.70) | когда-нибудь (пилот) | Ф2.5 пре-рег | D25 п.8–9, D39.66, D39.69 | +| 81 | **ja-преп B6-ja (сужено пост-сверкой D39.66)**: Поливанов-валидатор (`translit_policy` = «Phase 2»-заглушка, `backend/internal/store/migrate.go:187`=`translit_policy TEXT` и `backend/internal/store/migrate.go:195`=`ruby_reading`) + kana-омограф POS/known-word гейтинг / B6-токенизатор (`backend/internal/membank/memory.go:1181`=`KANA and HAN are deliberately NOT boundary-checked`); чек-лист kana-алиасов сида УЖЕ построен (backend/README §ja + `AttachRubyAliasesToManual`) — остаток в нём только дизамбигуация двойных чтений (тот же B6) | бэкенд | когда-нибудь (перед ja→ru) | ja→ru-пак (рядом 35) | D16.4, D17.1, D18, D39.66 | +| 82 | **Морфо-гейт РОДА** (C3: русский глагол прош. вр. при gender=hidden = механический спойлер-канал; «жалоба №1 читателей MTL»; python-сайдкар/pymorphy, связка с морфопроходом Decl из 73). **$0-прототип получен эксп-21** (`battery.check_gender`: карточки из подписанного сида, фильтр по именительному падежу, 86–112 сверок/арм — D39.117); движковый гейт не построен | бэкенд | когда-нибудь (Ф2-гейты) | отдельный пак (с 52) | 06-реестр C3, research/12, D39.66, **D39.117** | +| 85 | **Пилот-преп добор** (к переупаковке PACKAGE4): Bertalign GOLD-пары + zh→ru spot-check (D29.2в; GPL-тулинг отдельно) · fidelity-каскад R2 shadow с корпус-подготовкой (D25.2) · exp08 v3 пере-съём COGS до фиксации budget_usd (D21.8) | полигон | когда-нибудь (Ф2.5) | пилот-преп-промт | D25, D29, D21.8, D39.66 | +| **— ПАК-21 «чекеры»: РАСТВОРЁН (D39.62); шестёрка исполнена 2/6 фазой 2 (D39.64: #11 · строка 26), остаток — ниже —** | | | | | | +| 93 | **Остатки строки 93 после пачки (D39.82):** строгий OffLanguage (36а, deferred D39.78) · 分之-разметка прежде стройки DC2 word↔word (полигон) · F4-хвост: `redrive --dry-run` обходит pre-flight, а `store.Open` мутирует SPOF-файл (миграции + recoverReservations; коммент «mutates nothing» неверен) — pre-flight и на dry-run при существующей БД либо read-only план; заодно stat-скип точной формой `fs.ErrNotExist`; **обострение приёмкой D39.134:** на устаревшей БД `--dry-run` выполняет ПОЛНУЮ миграцию схемы БЕЗ restore point (write-open без шва migrate) — воспроизведено исполнением. ⚠ **Остаток НЕ однороден по гейту (сверка 02.08):** F4-хвост и строгий OffLanguage свободны, а `分之`-часть ГЕЙЧЕНА полигон-разметкой среза («строить вслепую против мандата» — якорь техдолга) ⇒ не подавать строку как «малое касание без гейта» | бэкенд/полигон | когда-нибудь | малое касание / полигон-слот | D39.78, D39.82 | +| 98 | **DC7 грейд-консистентность — пере-гейчен по сид-покрытию (D39.82):** замер пачки реален (25 юнитов/93 «разряд» ≠ канон «класс» на labels-финалах), НО финалы — прогоны до/вне сид-v2-канона, а грейды 甲/乙/丙/丁等 теперь approved-записи сида с decl-формами: mempostcheck флагнёт «разряд» промахом dst; строить DC7 только если ОСТАТОК девиаций переживёт сид-покрытие — замер на первом СИДОВОМ прогоне добора идеала; дом канона при стройке = book.yaml (как register_blocklist; ратифицировано D39.82 — НЕ dc-checkers.txt, посылка D39.79 исправлена) | бэкенд | когда-нибудь (гейт: первый сидовый прогон добора идеала) | замер остатка → решение | D39.79, D39.82, SMALLPACK §5-E1 | +| 28 | Банк-линт латиницы в dst или строгая форма языкового предиката (7 строк утечки алфавита проходят экран); сюда же хвост закрытой 128 (D39.102: NoDst-почти-сентинел, латиница-target — дословно не переехал при закрытии, восстановлен аудитом D39.140) | бэкенд | когда-нибудь (добор идеала — носитель «свежий мини-прогон» растворён D39.67, актуализация D39.79) | касание чекеров при данных добора (помнить оговорку 36а: «甲等 → класс Цзя» строгой формой не ловится) | D39.52, D39.62, D39.64, D39.79 | +| 28а | **Prompt-injection-проба входного текста** ($0): сепаратор ⟦TM-BANK-v1⟧ и якорь-подобные маркеры В ТЕКСТЕ КНИГИ — поведение среза/парсера/инъекции (книга = недоверенные данные; инструментов у моделей нет, но канал банкноты читает вывод по маркеру) | бэкенд/полигон | когда-нибудь | малая проба | сводка-ревью 26.07 | +| **— СВИП ГИПОТЕЗ —** | | | | | | +| 30а | **Перерисовка puml-диаграмм под пост-пак-20 пайплайн** (терминолог, банкнота отдельным файлом); дом диаграмм теперь `backend/docs/` — правятся одним коммитом с кодом (D39.80); PUML НЕ рендерить (гардрейл); ловушки activity-синтаксиса, стоившие реального бага 25.07, — `12-go-style-notes` §1 (дом на онбординг-пути бэкенда; строка держит указатель, а не сам факт — носитель с запланированной смертью для долговечного факта не годится) | бэкенд | когда-нибудь | ближайший пак, касающийся pipeline | аудит доков 26.07, D39.80 | +| **— ОТДЕЛЬНЫЕ ПАКИ/РЕШЕНИЯ (бэкенд, добор идеала) —** | | | | | | +| 31 | Слой-2: извлечение дискурс-норм/few-shot из ТЕЛ промтов (форсинг = ja→ru) | бэкенд | когда-нибудь | отдельный пак (идеал D39.33) | CURRENT-STATE, D39.33 | +| 33 | **native-Gemini судья** (Ф2-механизм) ; до прод-заводки: $0.01-проба thinking⊆max_tokens на боевом слаге (D22.3) + включить sanitizer в pipeline-c2 при оживлении (D33.4б) | бэкенд | когда-нибудь | отдельный пак (идеал) | CURRENT-STATE, D39.33 | +| 34 | **Генеральность нарезки** — ОСТАТОК после фазы 2: сами per-script коэффициенты (`est_out` ja завышен ~1.7× МОЛЧА · `EstimateTokens` недосчитывает кириллицу); консолидация класса письма СДЕЛАНА (один дом `DenseScript`, D39.64) — лечение = `Fertility`-map (строка 14) + офлайн-калибровка при боевом токенизаторе | бэкенд | когда-нибудь | строка 14 + отдельный пак (с ja→ru) | D39.37(5), D39.64 | +| 34а | **Экран кодировки не видит `` без XML-объявления** (епаб с gb18030-метой прочтётся как UTF-8) — до-паковая дыра, сознательно не тронута пачкой 14а (паритет со старым ридером) | бэкенд | когда-нибудь | отдельное решение | D39.54, SMALLPACK §8 | +| 35 | **Не-CJK майнер/банк**: en-детектора не существует (hanRuns=0), ja с zh-таблицами активно неверен (0/10); нужен второй ДЕТЕКТОР (прототип `mine_nonhan.py`) + G1–G10 требования generic-майнера (вкл. квадратичность G9 ≈4.6 ч) | бэкенд | когда-нибудь | отдельный пак generic-майнера (с ja→ru) | D39.37(8), D39.43, D39.50 п.8, POLYGON_PREMEASURE §6 | +| 36 | Кластеризация майнера глотает родовые титулы (族长/学堂家老 в кластере 葛家) — закрыто на границе сборки входа, сама кластеризация не чинилась | бэкенд | когда-нибудь | отдельное решение | D39.43, D39.45 | +| 36б | **Второе мнение по банку**: рецензент ДРУГОЙ моделью, несогласия — отдельной колонкой подписной таблицы (судья-с-декоем в роли рецензента; решает владелец, D39.46-ограничение не бьёт). ⚠ **Бэкенд-стройки НЕТ** (D39.69 закрыл по нужности); замер ИСПОЛНЕН (research/24, D39.102) — остаток = строка 5: рецензент спорных КЛАСТЕРОВ при ре-пробе 74, роутинг family/series-юнитами; переживёт замер → тонкая колонка наблюдаемости, не гейт | полигон (замер) → бэкенд (только если переживёт) | когда-нибудь (слот при ре-пробе 74, остаток строки 5) | замер остатка → решение | D39.69, D39.90, **D39.102** | +| 36г | **Проводной формат каналов пересказан прозой в каждом пар-промпте, парсер в Go, связи нет** — формат в шаблон движка (`{{banknote_format}}`); линты держат класс, дублирование остаётся | бэкенд | когда-нибудь (со следующей правкой промптов) | отдельное решение (Р5) | D39.58 | +| 37 | **Квадратичности: `AttachKWIC`** (16.8 с / 2000 кандидатов; фикс — многошаблонный поиск; ⚠ опция фикс-пака 128 НЕ взята — «чисто не ложится»: автомат в `membank` неэкспортирован, вынос в общий пакет = рефакторинг слоя, `terminology` PURE не может импортировать банк-стор — отчёт пака §4 п.5, D39.118) + src-правило банкноты при промахе чанк-пути (строка × длина книги; на 10 главах не видна) | бэкенд | когда-нибудь | отдельное решение | D39.45, PACK20_BANK_BUILD §8.5.1, D39.58, D39.118 | +| 38 | Смета не видит пере-покупку прохода терминолога на каждой итерации подписи (роль не пишет `chunk_status`, не видна `projectRebill`) · хвост приёмки №13: адрес чекпойнта батча = ординал при частотной сортировке ⇒ реюз чекпойнтов прохода ~0 на инкрементальной книге — **механика ПОДТВЕРЖДЕНА КОДОМ фикс-паком (§2 отчёта, D39.118):** G1 двигает состав юнитов и те же ординалы, на первом прогоне после пака перекупаются все бэнк-батчи (центы) | бэкенд | когда-нибудь | отдельное решение | D39.45, PACK20_BANK_BUILD §8.5.2, D39.102, D39.118 | +| 39 | S12 частичен: `malformedSeparatorAt` не ловит подмену слова разделителя и обрыв токена (комментарий обещает) | бэкенд | когда-нибудь | отдельное решение | D39.45, PACK20_BANK_BUILD §8.5.3 | +| 40 | `bankTokenBudget`: worst-case зашит zh→ru (признанная утечка §0; CJK-цель недобирает вдвое) | бэкенд | когда-нибудь | отдельное решение | D39.45, PACK20_BANK_BUILD §8.5.4 | +| 41 | golden: вторая фикстура С langpack (сейчас пинится только фолбэк-путь) ; + golden-счётчики голоса (хвост D39.58) ⚠ **ПРЕДМЕТ ШИРЕ ЗАЯВЛЕННОГО, испр. 05.09 по итогу веера.** Снято у прежней формулировки: «не пинится ничем» — ЛОЖНО, zh с настоящими langpacks гоняется в пяти интеграционных тестах; дыра именно в ПОБАЙТОВОМ пине. И «побочно это фикстура общности» — вывернуто: нынешний golden И ЕСТЬ доказательство цели №2 (пара БЕЗ пакета проходит книгу end-to-end байт-в-байт), вторая фикстура служит целям детерминизма и денег. **Настоящая цена дыры:** один из фолдов снапшота — руками поддерживаемая строка `RenderFormatVersion` (`backend/internal/membank/memory.go`); забыли бампнуть при смене байтов провода — денежная ось молчит, а контент-ось перекупает затронутые чанки БЕЗ гарда и БЕЗ согласия (`rebill.go`: «the CONTENT axis … re-bills exactly the touched chunks and is invisible here»). Единственный механический подстраховщик здесь — побайтовый golden, которого на langpack-пути нет. | бэкенд | когда-нибудь | отдельное решение | D39.37(6) | +| 42 | `prompt_override` — легальный обход гарантии слоя-2, сформулировать честно | бэкенд | когда-нибудь | отдельное решение | D39.37(7) | +| 43 | `request_log` без скоупа/ретеншена + `first_flag_reason` = третье представление истории попыток (корень — неразведённые скоупы) | бэкенд | когда-нибудь | отдельное решение | D39.37(9) | +| 44 | **Флор — выбор числа ПОСЛЕ ре-пробы 74; модель «thinking в completion» ПОЛУЧЕНА замером (D39.86): рычаг против неограниченного думания = `reasoning_effort`, флор не рычаг.** Мини-проба флора одобрена владельцем, промт не выдан; у dspro эффорт не настраивается (quirks 3а). Расхождение трекера с 74 снято D39.90. Археология дословно — `architecture/13-tech-debt-anchors.md` §Б-44. ⚠ **Вводная сменилась 13.08 (вахта §Б-108 СРАБОТАЛА):** вендор дал pro/flash настраиваемые уровни low/high/max — квирк 3а («у dspro эффорт не настраивается») устарел, пере-проба маппинга ПОВЕДЕНИЕМ + абсорбция в quirks — полигоном | бэкенд | когда-нибудь (триггер «приёмка 104» НАСТУПИЛ — D39.91, ручка заленжена; «сколько ставить» остаётся НЕзамеренным — нужен вариационный замер флора при `low`) | отдельное решение | D39.37(10), D39.86, **D39.90**, вендор 13.08 | +| 45 | `max_tokens`-упоры (две единицы) — вернутся на en-книге ; halve-chunk-on-retry (research/22 §2 №7) ОТКЛОНЁН D39.74 — вернуться сюда же при живых упорах | бэкенд | когда-нибудь | отдельное решение (с en) | D39.37(11) | +| 47 | M2-кэш / доктрина Д2 — кандидат на отдельную ратификацию | оркестратор/бэкенд | когда-нибудь | отдельное решение | D39.42 | +| 48 | Направленная банкнота — вернуться по замеру покрытия терминолога | бэкенд | когда-нибудь | отдельное решение | D39.42 | +| 48а | **Серийный шаринг банка** — РЕАЛИЗАЦИЯ (экспорт подписанного глоссария как сид-YAML следующей книги серии; спойлер-окна плющатся в since_ch=0); контракт round-trip держится тестом, самой фичи нет | бэкенд | когда-нибудь (перед второй книгой серии) | отдельное решение | D39.42 задел (а), PACK20_BANK_BUILD З-а | +| 48б | **Импорт «оригинал + чужой перевод» как режим данных терминолога** (target-агностичный вход есть контрактом; сам режим + провенанс источника + юр-сторона в юр-пакете) | бэкенд/владелец | когда-нибудь | отдельное решение + Ф2.5 (юр) | D39.42 задел (б), PACK20_BANK_BUILD З-б | +| 130 | **emitRankCap × writeAutoBank — ОСТАТОК после фикс-пака (D39.118):** $0-минимум ИСПОЛНЕН (дифф старого/нового авто-файла + WARN с именами выпавших; само-исключение сырого seed закрыто `unsignedEngineSurfaces` дофиксом приёмки); остаток = накопительный мердж авто-банка / освобождение слотов seed-rejects — СТОП-решение владельца (двигает банк → memory_version); материал для решения даст WARN со ВТОРОГО прогона (§6 п.8 отчёта пака) | владелец → бэкенд | когда-нибудь (гейт: WARN второго прогона) | СТОП-решение | D39.102 п.3, **D39.118** | +| 131 | **Кап инъекции не считает маркер и гендер-ноты**: `glossaryLineTokens` бюджетирует только «src → dst» (`memory.go:518-521` против рендера `:698-708`) — авто-книга (все строки Ambiguous с ⟨проверить⟩) превышает `glossary_token_budget` ~на 40–60% при budget 800; биллинг/потолки компенсированы (резервация по фактическому рендеру, `stagerun.go:469-477`), сам кап не исполняется. Фикс двигает состав инъекций → RequestHash → перекупка волн ⇒ СТОП-решение с названной ценой. ⚠ После строки 134 (единый блок, маркер снят с провода — D39.104) превышение пере-замерить: состав рендера сменится | бэкенд | когда-нибудь | СТОП-решение | D39.102 п.3 | +| 132 | **Стойкий (пост-ретрайный) аутедж ТОЛЬКО банк-провайдера валит весь ран** вопреки коммент-контракту «optional step never aborts» (`terminologist.go:630-634` — деградация только на ceiling; транспортные ретраи гасят transient, `httpllm.go:126-160`; потерь нет — чекпойнты реплеятся за $0): решить — деградировать в «термы неконсолидированы»+WARN либо честно переписать коммент | бэкенд | когда-нибудь | малое касание через СТОП-решение | D39.102 п.3 | +| **— ШОВ ДВИЖОК↔ПЛАТФОРМА: деньги и механизмы (D39.106/107 п.2) —** | | | | | | +| 136 | **Write-ahead intent + состояние `uncertain`-эскроу + `closing`**: холд НЕ освобождается по выходу юнита (сигнал обгоняет денежные события); spend не постится без свидетельства провайдера; расход сверх холда — полной суммой, превышение явной строкой убытка | платформа/бэкенд | скоро (промты по команде владельца) | стройка по research/25 | D39.106 | +| 137 | **Ночная сверка расходов с данными провайдера** (в движок цены входят float64 по ручной таблице `ledger/pricing.go` — систематика процентная; сверка приоритетнее споров об округлении) | платформа | когда-нибудь (до первого платного пользователя) | стройка по research/25 | D39.106 | +| **— НАХОДКИ ПРИЁМКИ ЭКСПОВ 18–20 (D39.108) —** | | | | | | +| 141 | **ОСТАТОК — работа В ДЕТЕКТОРЕ, и она НЕ про потерю текста.** ⚠ **Дыра, которой строка была заведена, ЗАКРЫТА лендингом D39.164:** сноска с ханьцзы («`[1] 蛊真人 — название романа.`») мимо детектора примечаний проходит по-прежнему, но поднимает класс `CJKLeak`, он `CosmeticOnly` (`backend/internal/checks/sanitizer.go:161-163`), юнит уходит `sanitizer_stripped` — и маркер дыры выдачи, заведённый паком «тихая порча», для НЕГО правдив. То есть читатель дыру ВИДИТ. Осталось: сноска БЕЗ ханьцзы («`[1] Название романа.`») не поднимает ни одного класса (замер сессии: `total=0`) и едет как есть — но текста при этом НЕ теряет, это лишняя добавка, а не дыра, и маркер на ней ДЕЗИНФОРМИРОВАЛ бы. Ловля таких сносок — правка самого детектора, отдельный предмет | бэкенд | когда-нибудь | правка детектора + тест | D39.108 (приёмка 20); половина закрыта D39.164 | +| 142 | **Механизм «гейты флагают → точечная починка по флагу» как прод-путь**: exp20 §3.3 — $0.0002/дефект, 12/12 (при ИДЕАЛЬНОЙ детекции); механизм конкурентов (research/22:179), у нас петля пака-16 за `enabled:false` (строка 13); детекторы «выдуманное слово»/«инверсия» прототипированы эксп-21. **ДИСПОЗИЦИЯ D39.117:** ОТКЛОНЁН как замена редактора (`C2/A_law` −3.75 Holm 0.0006; «$0.0002 чинит всё» мерилось при идеальных флагах и при реальной детекции пало), ПРИНЯТ формой «механический ПРЕ-ГЕЙТ перед редактором» — брак 5 клеток против 10/23 при половинной цене ($0.00298/$0.00602); ремонт ТОЛЬКО с банком (без банка ломает канон 0.917→0.895) | владелец → бэкенд | скоро (форма решена D39.117; ⚠ **порядок задан D39.190 п.3 — стройка ПОСЛЕ шагов 0–1 полигона**, а не по первой свободной смене) | бэкенд-промт | D39.108, **D39.117**, D39.190 п.3 | +| 143 | **Абсорбция норматива судейства в `09-pilot-protocol.md`**: разброс инструмента ДО замера · объявленный порог различимости · MQM-lite/error-span первичен, pairwise только для стиля · декой обязателен · запрет судьи семейства жильца арма | полигон/оркестратор | скоро ($0) | правка дока | D39.108, exp20 §7 | +| 144 | **Вахта: grok `reasoning_tokens` ВНЕ `completion_tokens`** — формула цены харнессов может недосчитывать (до $0.0325 на exp20); вендор-сверка биллинга xAI при следующем прогоне с grok | полигон | когда-нибудь (следующий xAI-прогон) | вендор-чек | D39.108 (приёмка) | +| 146 | **Два техдолга движка без строки трекера** (свип 08.08): `prices_checked` (120 д) гейтит read-only `report` и $0-resume — свежесть цен проверять только на ПЛАТНОМ пути (`03-implementation-notes:244`) · `cache_ttl` ↔ `cache_write_per_m`: цена записи в кэш задана под ОДИН TTL (5 м), при другом TTL расчёт врёт (`:246`). Оба жили только в справочнике якорей, то есть вне единственного трекера · **приёмка D39.134:** ценовой гейт держит и ДЕТЕКТОР самолечения деплоя — на стенде с протухшими ценами `status` даёт 10, а не 13, и цикл «поймал 13 → migrate → повтор» не наступает | бэкенд | когда-нибудь | малое касание | свип доков 08.08, D39.134 | +| 147 | **Транспортные частичные из research/21 без носителя** (свип 08.08): п.16 HTTP/1.1-escape на последней попытке как ДИАГНОСТИКА тихого усечения 2–8k [PARTIAL, GATED] · п.17 assistant-prefill continuation на `finish=length` вместо ре-рана всего вызова [PARTIAL, DEFER]. Оба помечены в ресёрче как отложенные и ни в одной строке трекера не появились | бэкенд/полигон | когда-нибудь | замер → решение | свип доков 08.08, research/21 §16–17 | +| 150 | **Sol-арбитраж — внешний контур вместо слепого чтения владельца**: пере-суд расходящихся контрастов эксп-21 (`A/F`: luna +0.84 против gemini +3.03 — расхождение 14 sd шума судьи-замены) и слепых пар эксп-22 руками владельца через подписку (третье семейство, high reasoning); пакеты готовит эксп-22 Ф0.4 (слепые метки · оба порядка · декой), транскрипты персистятся как голоса внешнего судьи; luna-клетки Sol не судит (своё семейство) | владелец + полигон | скоро (пакет арбитража — из существующего сырья) | эксп-22 Ф0.4 + руки владельца | **D39.117** | +| 151 | **Отказной режим связки**: эхо-мина черновика воспроизводима на материале (глава 11 — 3/3 попыток; частота 31% на zh), связка покрыла 9/10 подряд идущих глав против 10/10 у однопроходки — единственный довод ПРОТИВ связки во всём эксп-21; движку нужен fallback при невозможности годного черновика (вариация ре-гена · эскалация модели черновика · деградация в однопроходку) | владелец → бэкенд | когда-нибудь (до МАСШТАБА) | СТОП-решение | **D39.117**, exp21 §14 | +| 152 | **Слипание абзацев — слепое пятно детерминированного контура**: батарея на тех же текстах даёт ДРУГОЙ порядок армов (`D` — худший по судье — лучший по правилам), расхождение локализовано в слипании, которого не проверяет ни одно правило; правило в батарею полигона + кандидат в гейты движка | бэкенд/полигон | когда-нибудь | малое касание + тест | **D39.117**, exp21 §13 | +| 153 | **Чистый контраст мандата перевёрстки**: `D/D_` загрязнён (объём промта ×1.92 + вёрсточная строка + правило чэнъюй); уравненные промты и пере-гон ≈$0.35; по грязному контрасту мандат ВРЕДИТ по оси ФОРМА (−1.09 из −3.31 `D/A`) | полигон | когда-нибудь (опция эксп-22 Ф3 — реши сессия) | замер | **D39.117**, exp21 §16.3 | +| **— ХВОСТЫ ФИКС-ПАКА БАНКА (D39.118) —** | | | | | | +| 154 | **Одноруновая голова семьи** (`蛊`/`转`/`窍` едет в отдельном вызове от 12 своих поверхностей — якорь семьи обязан быть ≥2 рун) — включается ОДНОЙ строкой данных `family_containment_runes han 1`, Go не трогается; не включена: цена в размере юнитов не замерена | бэкенд | скоро — ✅ **ГЕЙТ СНЯТ 05.09: поле ПРИЕХАЛО.** Манифест публикует размер юнита в знаках — `source_chars` (плюс раздельно плотные/разрежённые), лендинг `81a89e9`, акт D39.206, **аддитивно, версию манифеста не двигало**. ⇒ «решение уровня ноты» больше не нужно, замер берётся. Ниже — археология гейта. ⚠ **ГЕЙТ ПАЛ И ОКАЗАЛСЯ НЕДОСТИЖИМ** (испр. 02.09, переведена из БЛИЖНЕГО веса): первый холодный прогон отработал 31.08, и он же показал, что назначенный замер этим путём НЕ БЕРЁТСЯ — манифест не публикует размеров юнитов В ЗНАКАХ вовсе (юнит несёт `id`/`first_*`, не длину). ⚠ Настоящее предусловие — новое поле контракта манифеста, то есть решение УРОВНЯ НОТЫ (`manifest_version`), а не строки бэклога: до него строка не гейчена ничем достижимым | строка данных по замеру | **D39.118**, отчёт §5 | +| 155 | **Скрипт-слепой резолв семей/серий**: han-правила режут кану и хангыль (синтетика: 24 катаканных имени с общим アリ → батч 8036 рун при бюджете 6000); живого вреда нет — пары в репо нет; та же слепота у серий уже в HEAD | бэкенд | когда-нибудь (преп ja→ru, с 81/120) | ja-пак | **D39.118**, отчёт §5 | +| 156 | **`banknote_truncated` — ПОЛ, а не счёт**: обрыв, срезавший сам разделитель, флага не даёт; буквальный фикс зажёг бы колонку на каждом обрыве в прогонах без канала — нужен гейт по `Gates.Banknote.Enabled` | бэкенд | когда-нибудь | малое касание | **D39.118**, отчёт §5 | +| 157 | **Пере-подтвердить `family_max_members=24` и `families_held`** на длинной книге (24 калиброван на дистилляции в 150 поверхностей; кап эмиссии 200 + реверс-секция дают другой список); если `families_held` велик — ослабить гард до «родство по любому члену юнита» вместо «по корню серии» | бэкенд | когда-нибудь — ⚠ **ГЕЙТ ПАЛ 31.08, ответ ОТРИЦАТЕЛЬНЫЙ** (испр. 02.09, переведена из БЛИЖНЕГО веса): прогон дал `families_held=0`, значит ослаблять гард не нужно. ⚠ Но замерено на ДЕСЯТИГЛАВНОЙ книге, а строка требует пере-подтверждения на ДЛИННОЙ — вывод действителен «на 10 главах» и протухнет на первой длинной книге. Указатель «§6 отчёта» заменён на греп-форму: `archive/reports/COLDRUN_V16_REPORT_2026-08-31.md`, греп `families_held` | замер → решение | **D39.118**, отчёт §7 п.7 | +| 158 | **Уверенность не гейтится данными пары**: канал снимает третью колонку у любой пары, чей промпт её попросит; у пары с ДВУХпольным промптом узкий риск «Пик␣␣99» (число ≤100 за двойным пробелом уедет в conf); при нужде — дата-декларация пары | бэкенд | когда-нибудь | дата-декларация | **D39.118**, отчёт §4 п.6/§7 п.8 | +| 159 | **Durable-имена эвиктнутых** (`retrieval_state.evicted_detail` = миграция; сегодня лог, и приёмка ратифицировала «этого достаточно») — заводить только при доказанной потребности, одним касанием с идемпотентностью миграций 49а | бэкенд | когда-нибудь (гейт: доказанная потребность) | миграция с 49а | **D39.118**, отчёт §7 п.2 | +| 160 | **Структура глав, Этап 0** ($0, wire-нейтрально): `titleRaw` в манифест (subtitle добывается `matchHeaderLine` и ПОНИЖАЕТСЯ в тело прозы (испр. D39.125), а не выбрасывается) + provenance у heading + тип chapter/fragment + вердикт структуры (бамп manifestVersion) · **дыра Р6**: projectRebill слеп к контент/позиционной оси (rebill.go:32-35) — ревизия структуры перекупила бы хвост МОЛЧА, закрыть read-path-расширением · слой пользовательских правок отдельным сайдкаром · **зонная половинка темы:** Ф-30 фронта / В-4 владельца (глава без заголовка на экране — метка из ДАННЫХ, К-3) ждут ровно эту строку; `heading` манифеста до неё = ВРЕМЕННЫЙ рендер движка (D39.122 п.2д) | бэкенд | скоро (ГЕЙТ ПАЛ словом владельца 15.08, D39.136 п.3: ставится ближайшим бэкенд-паком с мандатом максимального качества; ⚠ **испр. 05.09: блокер 236 МЁРТВ** — «писатель книги» закрыт D39.175 (30.08), и очередь его больше не держит. Живая диспозиция другая: **строка отложена ПОРЯДКОМ — D39.190 п.2**, то есть ждёт своего окна, а не предшественника; тесты структуры глав — узлом будущего холодного прогона) | пак | research/27 §6 Этап 0, D39.122 п.4, D39.136 | +| 161 | **Структура глав, Этап 1 «большой перекрой»** (единственное дешёвое resnapshot-окно — пока платная книга одна, ДО интейка): IR + формато-адаптеры (epub nav/NCX, fb2) + индуктор с валидаторами и вердиктами + третий версионный план паттернов (не в снапшот волн) + развязка чанкера от глав + банк-окна на chapter-ID + контент-адресуемый resume (долг D15.2) + формула Chapter.ID «окно» + роль title (мини-сессия названий: редакторский слот · инъекция банка · двухфазно вокруг подписи) + аддитивное расширение контракта 14; жизненный цикл дерева — research/27 §3а (решение владельца 09.08) | бэкенд (+фронт/платформа аддитивно) | скоро (постановка санкционирована D39.136 п.3: СНАЧАЛА дизайн-пак с мандатом максимального качества, стройка после ратификации дизайна; ⚠ дешёвое окно закрывается первой книгой внешнего пользователя) | дизайн-пак → ратификация → пак(и) | research/27 §3/§5/§6, D39.136 | +| 162 | **Структура глав, Этап 2**: in-band метки глав в потоке перевода (третий эшелон детекта + коррекция структуры по ходу черновой волны, §3а п.3) + канон-гейт названий ($0) + миграционные карты якорей (same/moved/split/merged/gone/new) + калибровочный корпус детекта в CI ⚠ Форма владельца 30.08: черновая модель отвечает МЕТАДАТОЙ в конец ответа, если посчитала строку фрагмента авторской разметкой главы — разметка едет попутно с черновиком без отдельного платного прохода; доверие — через фиксацию в манифесте и подтверждение спорных. | бэкенд + полигон | когда-нибудь (после Этапа 1) | пак + корпус | research/27 §5/§6 Этап 2 | +| 163 | **Версии модулей x/text|x/net двигают нарезку МИМО всех ключей** (NFC в NormalizeSource — таблицы модуля, не тулчейна; epub-токенайзер): бамп `go get -u` тихо меняет нарезку при свежих на вид манифесте/чекпойнтах/снапшоте — класс всей чекпойнт-плоскости, унаследован манифестом; вплести версии модулей (debug.ReadBuildInfo) в NormVersion/chunkerVersion либо явный запрет бампа без `--resnapshot` | бэкенд | когда-нибудь (до второго прогона книги) | малое касание | **D39.122**, приёмка (охотник №1) | +| 164 | **Rebill-проекция `status` с nil baseMemory завышает RebillUSD**: read-путь не материализует base-банк → renderedContentHashes даёт пустую инъекцию → repin недоопознан, строка считается re-pay (консервативная сторона, но противоречит комменту «status can never quote a different number than translate»); материализовать base-банк на read-пути либо смягчить клейм | бэкенд | когда-нибудь | малое касание | **D39.122**, приёмка (охотник №1); preexisting | +| 166 | ⚠ **ДВИЖКОВАЯ ПОЛОВИНА ПОСТРОЕНА 05.09** — `expected_usd` по главам, `book_once_usd`, `step_max_usd` в `manifest --json`/`status --json` (лендинг `81a89e9`, акт D39.206). Открыта ПЛАТФОРМЕННАЯ: числа публикуются и никем не читаются (`git grep -lE "StepMax|step_max" -- platform/` пусто). **Движковая поверхность оценки $/глава** (ставка-константа платформы $0.03 из exp08 v2 — временная мера беты, П-10 зоны платформы; честная оценка по книге/паре — движковая) | бэкенд | когда-нибудь | отдельный пак | D39.123 | +| 168 | **Состав волн пайплайна = пар-конфиг (данные), не общий хардкод**: вопрос владельца 10.08 «нормально ли под китайский строить весь бэкенд и конфиги?» — жильцы ролей и промпты уже конфиг/langpacks, но ТОПОЛОГИЯ волн (перепис · точечный edit-контур · без второго прохода) одна на всех пар; если фаза Д покажет разных победителей по парам (H-3/H-4: en-черновик+edit против zh-связки), состав волн уезжает в пар-конфиг данными; ревью-вопрос общности §0 `12-go-style-notes.md` | бэкенд | когда-нибудь (после данных фазы Д) | замер (фаза Д) → решение владельца → малое касание | слово владельца 10.08, промт фазы Д | +| 170 | **`tmctl init` — движок сам заводит книгу** (форма В развилки интейка): платформа зовёт $0-команду, движок пишет СВОЙ `book.yaml` — требования к полям живут там же, где проверяются (`config/book.go`); до неё бета живёт формой Б (рендер из деплой-шаблона платформой при создании книги, ратификация D39.130) | бэкенд | когда-нибудь (после беты формы Б) | малый пак | приёмка P5, **D39.130** | +| 172 | **Остаток после пере-пина DeepSeek (пин ИСПОЛНЕН и ПРИНЯТ — D39.137, `76049bb`):** (а) **схемное решение владельца по time-based** — доклад §5 отчёта вендор-сессии (рекомендация: пик оставить; scheduler-вариант строки 60 не начинать до ответа вендора «по какой отметке времени тарифицируется вызов» — вендором НЕ задокументировано — и замера доли пика; дешёвый рычаг: операционное правило «прогоны не стартуют в 01–04/06–10 UTC» — почти всё ×2 без строчки Go; гибрид «резерв пиком, сеттл по окну факта» назван) · (б) пере-калибровка ставки $0.03/глава (166/П-10; множитель счёта замерен) · (в) exp08 v3 (85) обязателен до budget_usd · (г) **вахта весов V4-Pro-0813** (класс D39.61): риг готов, порог ратифицированной ВЫБОРОЧНОЙ формы («≥4/5 прогонов N=5 достигают 6/6», D39.136 п.6б) **в риге ИСПОЛНЕН** паком честности — арифметика вынесена в `live_reprobe_threshold_test.go`, сам риг применяет её же. ⚠ **ИМЯ СТРОКИ ВВОДИТ В ЗАБЛУЖДЕНИЕ (испр. №18 17.08, сверено кодом):** названный риг меряет роль КЛАССИФИКАТОРА, а она ходит на **flash** (стендовый `pipeline.yaml:64` + артефакт прошлого прогона `model = deepseek-v4-flash`), тогда как сменившиеся веса — у **pro**, а pro у нас = РЕДАКТОР (`configs/pipeline-c1.yaml:62,76`). Владелец 17.08 санкционировал ТОЛЬКО вариант (а) — пере-съём классификаторного гейта, потолок $0.20, исполняется п.5 пака честности. **По этому прогону строку НЕ закрывать:** вопрос «сменились ли веса редактора» остаётся открытым, дешёвый вход к нему — данные фазы Д, где pro гоняется именно редактором (спросить полигон прежде, чем покупать новый замер) | владелец → бэкенд/полигон | скоро (схема — на владельце; вахта — после 16.08) | СТОП-решение (схема) + замер (вахта) | вендор 13.08, **D39.137**, строка 60, D30.4 | +| 180 | **`prices_checked` — одно поле на ВСЮ таблицу цен** (находка вендор-сессии, D39.137): бамп по факт-чеку одного вендора сдвинул 120-дневный гейт свежести остальным семи моделям (дедлайн уехал ~07.11→~13.12); лечение — пер-модельная дата проверки (правка схемы) ЛИБО ре-чек остальных вендоров отдельным заходом до исходного дедлайна | бэкенд | когда-нибудь (ре-чек вендоров — до ~07.11) | малое касание / вендор-заход | D39.137, отчёт §7.1 | +| 182 | **Wire-батч перед добором идеала — КОПИТЬ и вносить ОДНИМ касанием** (каждая правка двигает RequestHash / `memory_version` / снапшот = перекупка волн; дриблить по одной = платить пере-снапшот несколько раз): 46 экран цели (+предпосылка 113 фикстура) · 134 инжект-заголовки (гейт пал D39.108) · 131 кап инъекции · 140 банковый контур в shipping (СТОП-решение) · 105(а) вердикт-половина классификатора · 130-остаток (мердж авто-банка, гейт WARN второго прогона) · 14 ё-фолд (носитель «следующий пак общности») · **119+124(+115 пер-парный хеш EmbeddedVersion) — ОДНИМ дизайн-паком** (строка 124 требует принимать целиком; сверено кодом: `cutTag` фолдит `chunkerVersion`/`EmbeddedVersion`/`NormVersion` — `manifest.go:160-169`); вне батча свободен только 118 (tools/go.mod). Состав — аудит корпуса 15.08 (archive/reports/CORPUS_AUDIT_2026-08-15.md §В.г) | оркестратор → бэкенд | скоро (собрать к ратификации фазы Д; вносить перед первым платным прогоном добора идеала) ⚠ **СОСТАВ ОКНА 04.09 (D39.190 п.4 ратифицировал пере-снапшот единым актом):** в выданный вайр-батч вошли **210 · 113→46 · 134 · 140 · 184(а)**; СНАРУЖИ остались и это сказано вслух, а не умолчано — **131** (кап инъекции: своя цена и своё СТОП-решение, и сама строка велит «пере-замерить ПОСЛЕ 134», то есть её очередь следующая), **105(а)** и **14** (ждут следующего окна), **119+124+115** (только одним дизайн-паком), **160** (бампает `manifestVersion`, отложена ПОРЯДКОМ — D39.190 п.2), **142** (после шагов 0–1 полигона — D39.190 п.3). | координационная строка → промт(ы) батча | аудит 15.08, D39.134/136/137 | +| 173 | **`backupStamp` секундной точности**: два `translate` в одну секунду дают коллизию имени бэкапа и exit 1, маскируя класс «проект занят» (12) — метка до наносекунд/uniquify либо распознавать коллизию явно; преexisting, вскрыт ревью эмиттер-пака | бэкенд | когда-нибудь | малое касание | приёмка D39.131 | +| 175 | **Деплой движка «в полёте» — ДАЛЬНИЙ ОСТАТОК** (ближняя половина ИСПОЛНЕНА паком migrate — D39.134; правило свипа и settle запиненным бинарём — аддендум P6, D39.132). Остаток: (а) при СЛЕДУЮЩЕМ бампе схемы проставить в файл книги `application_id` + `min_reader_version` — данные-задел под окно совместимости, ~0 логики; (б) GC бинарей: удалять не пиненные ни одной незакрытой попыткой, последние 2–3 релиза держать для отката; (в) окно совместимости читателей / пин уровня книги — строить ТОЛЬКО по триггерам: много тенантов · бампы схемы еженедельно+ · потребители `status` кроме платформы. Археология захода — ресёрч 14.08 (вывод: exact-match читателей на деньгах = осознанный fail-closed, корень не выдёргивать, приделать дверь) | платформа/бэкенд | когда-нибудь (по названным триггерам; (а) — попутно первым бампом схемы) | данные-задел + малые касания | владелец 14.08, ресёрч 14.08, строка 139, D39.134 | +| 177 | **Гигиена restore point `tmctl migrate`** (находки приёмки ВНЕ карты отчёта; фикс-лист ФМ — запись приёмки 15.08, слайс [archive/PROGRESS-2026-08-14-15.md](archive/PROGRESS-2026-08-14-15.md)): ретрай в ту же секунду после сорванного шага = exit 1 «backup already exists» вне полосы — ровно на цикле самолечения платформы · kill -9 посреди шва оставляет РВАНУЮ копию под легитимным именем (ручной откат по ней = потеря данных; лечение — temp+rename) · копии restore point не подчищаются (повтор после срыва копит их) · SIGINT/SIGTERM в migrate не прерывают (ctx не доезжает) · комментарий migrate.go «no money touched» на no-op неверен (recovery зануляет leftover reserved) | бэкенд | когда-нибудь (следующее касание migrate/бэкапа) | малое касание + тесты | D39.134, приёмка №17 | +| 178 | **Калибровка `sense` банка** — слово владельца 15.08 (D39.136 п.4б): смысл должен быть «ёмкий и достаточный на всю книгу, но не слишком подробный» (образец: «спутница главного героя»); сейчас возможно КОРОТКОВАТ; замер длины/достаточности на подписанном банке → правка промптов банкноты/терминолога (двигает провод — цену назвать при внесении) | бэкенд/полигон | когда-нибудь (касание банка) | замер → правка промптов | D39.136 п.4б | +| 183 | **Батч 0.3.0 — ОТРАБОТАН ЦЕЛИКОМ** (батч D39.142 + дофикс D39.143, `86720cf`; промт в архиве). ⚠ Номер канона в этой строке НЕ держим — канон ушёл на **0.9.0** (D39.180), лента миноров — в шапке. **ЖИВОЙ ОСТАТОК ОДИН — (б):** зеркало `frontend/docs/api-contract/` + типы + моки + гейт утечки, первое касание фронта при разморозке; расхождение канона и зеркала ВРЕМЕННО ратифицировано D39.142 п.5. Пункты (а) и (в) СНЯТЫ (D39.153; D39.144 п.4)| оркестратор ⚠ **ОЦЕНКА «ПЕРВОГО КАСАНИЯ» ЗАНИЖЕНА — измерено 05.09 веером.** Записанное «синк зеркала + перегенерация типов ОДНОЙ командой» неверно по ОБЪЁМУ: перегенерация — одна команда, но она вскрывает переписывание слоя данных. Замерено: 16 операций против 21; 40 новых имён схем в каноне и 10 МЁРТВЫХ в зеркале, на которые `src` ссылается 31 раз; две ручки, которых платформа не отдаёт вовсе. Плюс гейт версии у фронта читает СВОЁ зеркало (строка 268), то есть отставание он не увидит и после синка. | скоро (остаток = только (б) зеркало фронта при разморозке) | P7 → фронт при разморозке | D39.138, D39.142, **D39.143** | +| 185 | **Дописывание глав в ТЕКУЩУЮ книгу («костылей не будет»):** форма `POST /books/{id}/parts` + ответ «сколько глав добавится, что сдвинется и почём» ДО подтверждения; экономика уже позволяет В КОНЕЦ за ~$0.02 (ключ вызова позиционный, исходник вне снапшота), вставка в середину = МОЛЧАЛИВАЯ перекупка хвоста ~$9–11/500 глав — движковый гейт против молчания ОБЯЗАТЕЛЕН (родня дыры Р6 строки 160); платформа второй файл принять не может (re-parse нет); ja-мина: новый ruby-алиас двигает `memory_version` → снапшот (громкий `--resnapshot`, уточнение приёмки); полный $0-резюм хвоста — предусловие D15.2 (строка 49) | бэкенд+платформа+контракт | когда-нибудь (вместе со строками 160–162 — дизайн в паке 161) | дизайн-пак 161 → стройка | research/28 Б-19а/§8 п.7, D39.138 п.2г | +| 186 | **Сеть: перечитывания ничем не удешевлены** (замер 16.08: дерево 2283 глав = 250 КБ на каждый кадр `status`, фокус-рефетч 12 вкладок = 562 КБ — самый частый трафик порождает переключение вкладок, не пайплайн; гипотетический кадр банка на главу = 372 МБ/прогон; сжатия/ETag/304 нет НИГДЕ): план по эффекту — (1) gzip на текстовых ответах, НЕ на SSE (2) `ETag`/`If-None-Match`→304 на списочных GET (3) скоуп в кадре (id+версия, БЕЗ текста) (4) дельта-чтение банка/замечаний `?after_version=` (5) `staleTime` у клиента; шаги 1–2 — платформа (её же `platform/docs/PLATFORM_DIRECTION.md`, греп `Условные запросы`), семантика — в спеку батчем 183; транспорт НЕ менять (решение владельца по §5б) ⚠ **ШАГИ 1–2 ПОСТРОЕНЫ И ЗАЛЕНДЕНЫ P7 (D39.153)** — gzip на JSON и НЕ на SSE + `ETag`/`If-None-Match`→`304` на коллекциях, карточке книги и `/capabilities` — **и ПЕРЕ-ПРОВЕРЕНЫ ЗАМЕРОМ 28.08** (воркфлоу-ревью P9 на стенде, приёмка D39.162): банк 437 Б холодным → повтор с `If-None-Match` даёт **304 / 0 Б**; юниты главы 3008 Б → **740 Б gzip (×4.1)**; ниже порога 1024 Б gzip честно НЕ применяется; SSE корректно не сжимается. Остаток — шаги 3–5 | платформа (+контракт/фронт) | скоро (остаток: шаги 3–5) | мидлварь/edge платформы + батч 183 + разморозка фронта | research/28 §5б/Б-11а, D39.138 п.2д | +| 188 | **Носитель события «ре-проба 74»** (аудит D39.140: событие ждали строки 5 · 36б · 44 и шапка CURRENT-STATE, а владельца у него не было — строка 74 закрыта D39.91): дешёвая ре-проба flash при ПЕРВОМ платном прогоне добора идеала (D39.63 п.4) + слоты, подвешенные на неё: рецензент спорных кластеров банка (остаток 5) · замер второго мнения (36б) · выбор числа флора (44, после одобренной мини-пробы) · итерация №2 редакторов (D39.22/63) · выборочный порог 116 в риге (дописка 172-г) · решение о включении ре-гена перед эскалацией (экс-77, D39.64: «включение — решением при ре-пробе 74»; ручка построена, мертва во всех конфигах, ре-ген ≈7.6× дешевле эскалации) | полигон/бэкенд | скоро (гейт добора идеала — первый платный прогон) | проб-пакет при первом платном прогоне → решения по слотам | D39.63 п.4, D39.91, аудит D39.140 | +| 189 | **Мультиязычность фраз ЛОГОВ и АРТЕФАКТОВ движка — вторая половина слова владельца 15.08** (D39.136 п.4а «фразы ВСЕХ зон»; первая половина — юзерский провод — решена ревью 28 Б-1/батчем 183): фразы в `bank-stop`/статусных артефактах и логи движка вне контракта, носителя не было (research/28 §6, строка Ф-61: «носителя назвать отдельно» — аудит D39.140 подтвердил: не назван); разобрать, что из этого читает ПОЛЬЗОВАТЕЛЬ (артефакты банка — да, через проекцию платформы) и что оператор (логи — легитимно английские) | бэкенд | когда-нибудь (до второй локали интерфейса) | разбор → точечная правка | research/28 §6, D39.136 п.4а, аудит D39.140 | +| 190 | **Кросс-СЕМЕЙНЫЙ проход контракт-ревью** (не-Claude опровергатели; буква заказа владельца D39.136 п.5 «кросс-модели», исполненная в ревью только кросс-тирами Claude — ограничение честно заявлено research/28 §7/§10): проверка вердиктов доклада моделью другого семейства полигонным контуром; жила только колонкой «ЖИВОЕ» реестра нот — аудит D39.140 дал строку | полигон | когда-нибудь (после фазы Д; перед лендингом батча 183 — если владелец захочет второй рубеж) | полигон-слот с внешним провайдером | research/28 §10, аудит D39.140 | +| 192 | **Пост-ридинговый цикл правок банка — «наше подумать» владельца 16.08 (записано, чтобы не потерялось; точную механику «не продумал ещё никто и нигде» — его слово).** UX-модель целиком: юзер нажал перевод → черновая волна + майнинг вместе → на фронте появляются ЧЕРНОВОЙ перевод и ЧЕРНОВОЙ банк · подписывается ВЕСЬ банк одним ОК (D39.144) → перевод уходит в доработку · дальше юзер ЧИТАЕТ, и его опции: поправить термин в банке ЛИБО добавить свой → кнопка «поправить» → пере-генерация, которая по ВХОЖДЕНИЯМ правит запрошенное. Открытые вопросы дизайна: что именно перегенерируется (вхождения ключа · затронутые юниты · со сметой и согласием?) · нужен ли движковый ТОЧЕЧНЫЙ РЕДАКТОР (полигон над этим работает — фаза Д) · форма в контракте (ручки нет) и на экране. Уже лежит под ногами: движковый re-edit по ключу банка со сметой и $0-пере-пином ПОСТРОЕН (строка 49: `repin.go`/`rebill.go`, D39.42 п.5/D39.45) · пометка неподписанных строк · дельта-чтение банка (0.3.0). НЕ проектировать до полигонных итогов; затем дизайн-пак на их результатах → слово владельца → стройка | владелец+полигон → бэкенд/контракт/фронт | когда-нибудь (триггер: итоги фазы Д по точечному редактору) | дизайн-пак после полигона → слово владельца → стройка | слово владельца 16.08, D39.144 п.1 | +| 195 | **ОСЬ «идентичность оплаченной работы» — переселена в дизайн-пак 124 (решение владельца 17.08, вариант А; D39.151).** Как САМОСТОЯТЕЛЬНАЯ стройка ЗАКРЫТА: маркер `snapshot_id`/`run_id` на `checkpoints` отдельной колонкой НЕ строится. Причина — внешний разбор опроверг посылку «колонка = тождество»: $0-пере-пин законно переносит строку на новый снапшот со СТАРОЙ ценой (`stagerun.go:96-105`, сверено оркестратором), у старых чекпоинтов бэкфилла нет вовсе (`jobs.snapshot_id` перезаписывается каждым ре-снапшотом) ⇒ вывод-обход остаётся в коде навсегда как legacy-ветка, а колонка лишь добавляет рядом второй путь. **Настоящий корень глубже:** в сторе нет первоклассной связи «строка диспозиции ↔ вызовы, которые её оплатили»; снапшот на чекпоинте — прокси, а не примитив. ⚠ Границы семьи сужены тем же разбором: 49 и 195 — про РАЗНОЕ (49 = когда переиспользование законно, 195 = как честно посчитать будущую покупку), общий у них субстрат, не задача; из 124 родня только ось (в). **Срочности нет:** под контрактом D39.150 («направление ошибки, не точность») ни один исход не занижает молча — недостача несётся историческими деньгами С РАСКРЫТИЕМ, пойманный откат называется вслух. Остаточные нарушения контракта чинятся БЕЗ схемы: 197 и 194 | бэкенд | когда-нибудь (гейт — триггеры пака 124: дописывание глав 185 · МАСШТАБ · первый внешний потребитель числа) | ось дизайн-пака 124 | **D39.151**, внешний разбор 17.08 | +| 196 | **Остаточный класс строки 176: неперехватываемые `fatal error` Go** (конкурентная запись в map, OOM, стек-оверфлоу) по-прежнему дают exit 2, то есть читаются платформой как «завершено с флагами» — `recover` их не ловит по устройству языка (подтверждено линзой шва исполнением). Строка 176 закрыта для ПАНИК, не для fatal. Лечение — вне exit-контракта: сторож процесса у платформы либо маркер живости в артефакте прогона | бэкенд/платформа | когда-нибудь | отдельное решение | приёмка №18, линза шва | +| 197 | **Фикс-лист приёмки пака честности ФЧ-1…ФЧ-8** — восемь пунктов класса «заявленное не прибито» и «текст обещает больше числа», ни один не блокировал лендинг. **Тело списка дословно, с весами и с секцией «что НЕ проверено», — [archive/PROGRESS-2026-08-17.md](archive/PROGRESS-2026-08-17.md), запись приёмки №18** (D39.149). Здесь держим только ратифицированное: **ФЧ-5 РЕШЁН владельцем 17.08 (D39.150): прайсить по модели, которую стадия резолвит СЕЙЧАС, + округление вверх и оговорка в тексте согласия.** Носителя-сессии НЕТ — по слову владельца 17.08 пока только записано | бэкенд | скоро (следующее касание денежного пути; ФЧ-5 обязателен до первого пере-прогона со сменой модели) ⚠ **СОСТАВ ПЕРЕ-СКОУПЛЕН 04.09:** ФЧ-1/ФЧ-4/ФЧ-5 закрыты паком «число согласия» (D39.187); **ФЧ-6 по коду выглядит ЗАКРЫТЫМ** — отказ проекции репортится базисом, отчёт не валится (`backend/internal/pipeline/status.go`, греп `RebillBasisFailed`); **ФЧ-7 отдан проверкой** в вайр-батч (воспроизвести панику поверх пойманного потолка, чинить только если воспроизводится); **ФЧ-2/ФЧ-3/ФЧ-8 НЕ ПРОВЕРЕНЫ никем** и остаются живым остатком строки. | дофикс-промт ЛИБО попутно ближайшим паком | **D39.149**, **D39.150** | +| 198 | **Апгрейд движка стирает замечания и счётчики книги БЕЗВОЗВРАТНО — композиция двух половин, каждая известна по отдельности** (приёмка P7, линза «вне карты», обе половины пере-прочитаны оркестратором). Платформа при смене `manifest_key` сносит ВСЕ `unit_resolutions` книги (`platform/internal/pgstore/readmodel.go:164-165`), рассчитывая, что поток их пере-наполнит; движок анонсирует юнит РОВНО ОДИН РАЗ за жизнь книги — ключ `unit::::` БЕЗ метки нарезки (`backend/internal/pipeline/events.go:399-400`), а леджер анонсов переживает прогоны (`backend/internal/store/outbox.go:96` «already announced… by one that ran before it») ⇒ совпавшие координаты не переанонсируются НИКОГДА. Обостряется порядком: долг на материализацию ставится только на ГРАНИЦАХ работы, поэтому первая зачистка после апгрейда случается в КОНЦЕ первого пост-апгрейдного прогона и сносит замечания ТОГО ЖЕ прогона, за который заплачено. Следствия на проводе: «0 из N» на переведённой книге навсегда · шкала снова предлагает купить переведённое · замечания читателя исчезают. **Лечится с обеих сторон:** движковая половина — метка нарезки в ключе анонса (решение зоны движка), платформенная — не сносить вслепую либо восстанавливать из экспорта. ⚠ Гейт холодного прогона: смысл упражнения — гонять книгу против МЕНЯЮЩЕГОСЯ движка, то есть первый же апгрейд обнулит библиотеку | бэкенд + платформа | **скоро (до первого реального пользователя И до холодного прогона с апгрейдами)** | связка: решение по ключу анонса в движке → правка платформы | приёмка P7 (D39.153) | +| 201 | **Движковое «Глава N» доезжает читателю ВНУТРИ текста, обходя дисциплину `heading: null`** (линза шва P7, пере-прочитано оркестратором): `backend/internal/pipeline/export.go:58`=`ApplyHeading` (испр. оркестратором №20 30.08: якорь уезжал с `:230` и с `:266` — код растёт) приклеивает детерминированный порядковый к экспортному тексту первой юнит-главы (`ce.FinalText = chunk.ApplyHeading(...)`), колонка `Source` при этом остаётся heading-stripped. Платформа переносит обе как есть и честно отдаёт `heading: null` — то есть клиент нарисует СВОЙ порядковый на языке своего интерфейса над абзацем, который уже начинается с русского «Глава N», а исходная колонка соответствующего маркера не несёт: пара визуально рассинхронизирована на каждой первой главе. Конкретное следствие открытого К-2 контракта; родня движковой строки **160** (глава без заголовка) | бэкенд | когда-нибудь (с 160) | отдельное решение | приёмка P7 (D39.153) | +| 203 | **Хвосты контракта после синка 0.4.0 — ОТКРЫТ ОДИН ПУНКТ, остальное исполнено** (тела релеев — `platform/docs/archive/P7_ACCEPTANCE_HANDOFF_2026-08-17.md` §7; сюда переписан НЕ текст, а статус — один носитель на факт). **ИСПОЛНЕНЫ и сверены грепом при лендинге:** (а) минором 0.5.0 (D39.161) · (б) · (д) · (и) поле `stop_requested` (D39.152) · (л)(м)(н)(о) контрактной сессией — остаток по фразам Приложения А несёт строка **204** и лист владельца. **(г) наполовину** — `unspecified` ратифицирован в каноне (`docs/architecture/14-api-contract/openapi.yaml:2168`=`is reserved and is the server`), открыта только ГРАНИЦА ступеней замечаний (две ступени при девяти рангах движка); ⚠ её прежний носитель — строка 148 — СНЯТ 21.08 по слову владельца. **(з) СНЯТ как ратификация 22.08 сквозной трассировкой (разбор, на который ссылается строка 191):** конфликта моделей НЕТ — гейт движка проверяет полноту не ПОДПИСЕЙ, а ФАЙЛА решений, и ОДИН файл со всем банком его снимает (`loadMinedDelta` штампует только `Source`, `mining.go:855-867` → опущенный статус дефолтится в `approved`, `membank/memseed.go:130`=`status = "approved"` → `unsignedEngineSurfaces` выбрасывает лишь `Source=="mined" && Status!="approved"`, `mining.go:710-719`). Пере-диспозиция 27.08 (D39.158 п.7): движковый гейт полноты УСТРАНЁН, не обойдён; остаётся снять обход в платформе — одна боевая строка (`platform/internal/runs/spawn.go`, `--verify-bank` не передаётся на resume) плюс семь строк ставшего ложным обоснования, работа платформенного пака. **ОТКРЫТО РЕАЛЬНО — (к):** ключ `project_db` в `book.yaml`, договорить, кто им владеет: шаблон оператора его не содержит, движок делает необязательным. ⚠ Следствие «на штатном деплое банк не читается» ОПРОВЕРГНУТО живым кодом: путь публикует ДВИЖОК конвертом артефактов, пустой путь — ГРОМКИЙ отказ (`platform/internal/runner/artifacts.go:39`=`the engine published no bank read-out path`); остаток (к) чисто договорной| контракт/доки | скоро (следующее касание контракта) | контрактная сессия | приёмка P7 (D39.153) | +| 204 | **Движок не публикует причины флагов ДАННЫМИ — карта причин у платформы рукописная и расходится молча** (релей §7(в) хендоффа P7; зона платформы в чужой бэклог не пишет и просила строку сюда — `platform/docs/archive/platform-PROGRESS-P7.md:206`). Сегодня `platform/internal/ingest/notes.go` держит рукописную копию закрытого словаря ЧУЖОЙ зоны: причин движка **16** (испр. 05.09 — шестнадцатой приехала `off_target_lang` → `wrong_language` с минором 0.10.0; прежняя редакция говорила 15 и это ровно то расхождение, которое строка предсказывала) → коды замечаний контракта. Импортировать движок платформе нельзя (D39.85 — разные модули), поэтому расхождение появится молча в тот день, когда движок добавит причину: платформа отдаст `unspecified` и напишет ERROR в лог, то есть деградация честная, но карта протухнет незаметно. ⚠ **Правила заполнения контрактных фраз по этим причинам УЖЕ НАПИСАНЫ** и выводить их заново не надо — компаньон `14-api-contract/README.md`, греп `по ДОККОММЕНТУ` (фраза пишется по доккомменту `disposition.go`, а не по имени константы; класс 2 схлопывается в ОДИН код). Лечение: движок публикует свой словарь причин артефактом-данными (тем же классом, что манифест и сайдкары банка), платформа читает его вместо копии. ⚠ Класс: носителем был ТОЛЬКО регистр платформы (PD-246) — обязательство к ЧУЖОЙ зоне жило внутри зоны автора | бэкенд | когда-нибудь (со следующим касанием эмиссии флагов) | отдельное решение | приёмка P7 (D39.153), релей §7(в) | +| 207 | **Пол самосогласованности манифеста стоит только у материализатора, интейк тот же документ ПРИНИМАЕТ — и по такой книге можно ОПЛАТИТЬ прогон** (`PD-367`, вторая волна ревью P8-FIX). Манифест `{ChaptersTotal: 120, UnitsTotal: 400}` с пустым списком глав `Whole()` отвергает, а `books.Parse` заводит книгу `not_started` с `chapter_count=120` и пустым деревом; потолок считается ОТ `chapter_count`. **Очевидное лекарство опровергнуто исполнением самой зоной:** применить `Whole()` на интейке нельзя — вся батарея интейка ездит на манифестах без списка глав, контракт интейка это только счётчики. Значит решение не зонное: либо контракт интейка меняется, либо пол ставится в другом месте цепи | оркестратор → платформа | скоро | нужно решение (лекарство ломает запиненный контракт интейка) | D39.154 п.10, `PD-367` | +| 209 | **Риг живых проб не может залогировать тела запросов ни при каких env** (находка бэкенд-пака честности 17.08, оставшаяся без носителя до аудита доков 22.08): `LOG_LLM_BODIES=1`+`LOG_LEVEL=debug` объявлены носителем тел, но ключ читается из `obs.ReqInfo` контекста, а `live_reprobe_test.go` строит ctx БЕЗ `WithReqInfo` — гейт `obs/logging.go` не пропускает. Обход, которым пользовались: ручной дамп сообщений в файл. Цена — каждая живая проба, которой нужно прочитать провод глазами, платит за обход заново | бэкенд | когда-нибудь (следующее касание рига живых проб) | малое касание (`WithReqInfo` в риге) + пин | пак честности 17.08, вынесено аудитом доков 22.08 | +| 213 | **ОСТАТОК — одна строка в ДЕВ-пути: супервизор зашивает `"book.yaml"` мимо константы `ConfigFile`** (`platform/internal/ingest/supervisor.go:142`=`"status", "--config"`). ⚠ **ГЛАВНАЯ половина ЗАКРЫТА лендингом P9 (D39.162):** путь банк-экспорта берётся из конверта артефактов движка (`platform/internal/runner/artifacts.go:28-35`; пустой путь — ГРОМКИЙ отказ), нестрогий парс `book.yaml` и собственный `projectDB()` снесены. Осталась ровно та тривиальность, которую строка называла рядом с дефектом. ⚠ Пере-именование банк-экспорта в фикс-имя рядом с `events.jsonl` — ЛОМАЮЩЕЕ, его место в окне строки **161**, НЕ здесь | платформа | когда-нибудь (одна строка, следующим касанием зоны) | правка дев-супервизора | консилиум шва 22.08; главная половина — D39.162 | +| 214 | **Подпись банка не оставляет на банке НИ ОДНОГО следа.** Единственная долговечная запись акта подписи — булев `bank_released` на прогоне (`platform/internal/pgstore/runs.go`, греп `bank_released` (номер строки двигает живая сессия зоны)): кто и когда подписал, что именно вошло в подписанный набор — не хранится нигде. Следствие: пост-фактум ответить «почему в книге этот перевод термина» нельзя, а при пере-нарезке или пере-прогоне восстановить намерение человека не из чего. ⚠ **ЧАСТИЧНЫЙ ответ появился с дверью правок (D39.162):** её документы решений — долговечная запись того, ЧТО владелец решил, и они переживают прогон. Не отвечено по-прежнему: КТО и КОГДА подписал, и что именно вошло в подписанный набор. Всплыло трассировкой цепи банка 22.08, подтверждено пере-проверкой | платформа + бэкенд | когда-нибудь (с трубой доставки правок, D39.156) | отдельное решение о провенансе подписи | трассировка цепи банка 22.08, пере-проверено №19 | +| 227 | **`signature` в квитанции двери правок считается от карты, которую переписывает ЛЮБАЯ граница майнинга** (находка воркфлоу-ревью P9, 28.08): запись карты стоит ВЫШЕ решения о стопе (`backend/internal/pipeline/mining.go:192`=`writeFileAtomic(r.signatureMapPath()`), поэтому `signature != null` НЕ означает состоявшегося стопа подписи; `surfaces`/`undecided` дрейфуют между двумя вызовами владельца, а `undecided: 0` достижим при НЕпредъявленных решениях (кап top-200 вытесняет). ⚠ Починка аддитивна и носитель для неё уже есть: карта несёт СВОЙ идентификатор (`backend/internal/membank/decisions.go:981`=`id, err := seed.SignatureMapID(content)`), а шов его не читает — отдать идентификатор в квитанцию и судить по нему. Цена сегодня мала (поле информационное, гейтом не служит) и растёт вместе с экраном подписи: именно он будет решать «что я подписываю» по этому числу | бэкенд | когда-нибудь (гейт: заказ экрана подписи) | аддитивная правка квитанции | воркфлоу-ревью P9, D39.162 | +| 228 | **Отклонённая поверхность возвращается АЛИАСОМ уцелевшей строки — движок не держит того, что канон уже обещает** (находка воркфлоу-ревью P9 в форме Д1, УЗКО пере-сформулирована бэкенд-сессией 28.08 и принята приёмкой): канон говорит дословно «declining a surface removes EVERY window of that surface» (`docs/architecture/14-api-contract/openapi.yaml:2344`=`declining a surface removes EVERY window`; адрес пере-нацелен 02.09 — минор 0.9.0 сдвинул прежний 2051), а эмиссия майнера энтити-широка (`backend/internal/pipeline/miner_emit.go`, `clusterTouches`), тогда как фильтр авто-банка ключуется только по собственному `src` строки (`backend/internal/pipeline/mining.go:179`=`NormalizeSourceKey(m.Src)`). ⚠ **Правильная форма — снять АЛИАС со строки, а не снести строку:** расширение `decline` до энтити противоречило бы ратифицированному контракту, и именно поэтому бэкенд-сессия применила право §9 и НЕ чинила это попутно. Предмет — банковая онтология (`18-bank-ontology.md`), не тихая порча | бэкенд | скоро (гейт: заказ по читающей стороне банка) | отдельный заказ узкой формы | воркфлоу-ревью P9; форма — бэкенд-сессия 28.08, D39.164 | +| 229 | **Снапшот не фолдит модель ВНУТРЕННИХ гейтов — флип провода под неизменным `request_hash`** (самонаходка бэкенд-сессии 28.08, подтверждена приёмкой): снапшот фолдит `Capability` СТАДИЙНЫХ моделей и их эскалации (`backend/internal/pipeline/snapshot.go:316-340`), но модель `gates.terminology.model` / `gates.repair.model` (`backend/internal/config/internal_call.go:72`) не фолдится сознательно — а терминолог шлёт ДВА системных сообщения, так что смена оси `capabilities.system_messages` у провайдера, которым пользуется только гейт, меняет байты запроса при неизменном хеше: тихий false-hit класса D5.2. ⚠ **Сегодня ЛАТЕНТНА и денег не стоит — проверено приёмкой: гейта `terminology` нет НИ В ОДНОМ конфиге репозитория** (`grep -c terminology configs/pipeline-c1.yaml` = 0). Триггер починки — день, когда гейт включат с провайдером, объявляющим НЕдефолтную возможность. ⚠ Цена лечения — денежная: фолд гейт-моделей сдвигает хеши и обесценивает чекпойнты; дешёвая форма — фолдить ТОЛЬКО недефолтное (приём `omitempty`, прецедент `MinMaxTokens`), тогда сегодняшние снапшоты остаются байт-равными | бэкенд | когда-нибудь (гейт: включение внутреннего гейта либо следующее касание снапшот-контракта) | правка снапшот-контракта | самонаходка бэкенд-сессии, D39.164 | +| 230 | **Инертный `decline` подписанного сид-терма отвечает `already_applied` вместо единственной работающей инструкции** (названный размен пака «тихая порча», D39.164): сузив отказ по поверхности ради СХОДИМОСТИ повтора, движок потерял поучение в одном углу — когда отказ и записан, и по-прежнему инертен против `glossary_seed`, пользователь получает «уже применено» вместо «убери терм из сида». Сходимость сочтена более тяжёлой обязанностью (на ней стоит вся раскладка класса 15 и синхронная дверь платформы), но размен РЕАЛЕН. **Форма закрытия — поле отчёта со стоячим фактом**, то есть аддитивная правка формы шва: платформенный `BankReport` — аллоулист, лишнее поле на провод не уедет само | бэкенд + контракт | скоро (с ближайшим касанием отчёта двери) | аддитивное поле отчёта | размен пака «тихая порча», D39.164 | +| 232 | ⚠ **ЛИД ПРОТУХ — испр. 05.09: вторая половина (слот гранта на прерванном между волнами юните) ЗАКРЫТА** паком «число согласия» (`D39.187`, пин `TestAUnitInterruptedBetweenWavesTakesNoSecondSlot`; эррата 03.09-а). **Настоящий остаток** — две схемные оси («первая редакторская стадия», «прерванная пере-делка») и отложенное слово владельца о семантике переноса. **Ось «свежий/пере-делка» выведена из ПОЛНОТЫ СТРОК, а не из факта отгрузки** (D39.170, находки охотника 3 и 4). Следствия ДЕНЕЖНЫЕ на слух покупателя: добавление стадии в пайплайн превращает ДОЧИТАННУЮ книгу в «3 unit(s) NEVER delivered» и приглашает купить её снова; юнит, прерванный между волнами (signature stop, денежный потолок, Ctrl-C), второй раз считается свежим и тратит слот гранта повторно — замерено 4 купленных юнита → 2 главы. Носитель у движка УЖЕ есть: реестр анонсов `events_outbox.once_key` (`backend/internal/pipeline/events.go:401`=`unitOnceKey is the identity of one announcement`), ключ `unit:<книга>:<волна>:<глава>:<юнит>`, монотонный на всю жизнь книги и переживающий и добавление стадии, и обрыв между волнами. ⚠ **ПЕРВАЯ ПОЛОВИНА ИСПОЛНЕНА 31.08** (`bb541a8`, экземпляр A11; испр. 02.09): читающий метод `store.AnnouncedOnceKeys()` построен, его докстринг называет эту строку по номеру, предикат — `delivered[key] && unitShipped(rows)`. **ЖИВОЙ ОСТАТОК — ВТОРАЯ ПОЛОВИНА:** юнит, прерванный МЕЖДУ ВОЛНАМИ, повторно тратит слот гранта (разбор — `backend/docs/MONEY_HONESTY_REPORT.md` §4.5). ⚠ РАЗВИЛКА, которую надо назвать в промте: ключ несёт ВОЛНУ, значит «юнит отгружен» — факт per-wave. **Ответ есть и он не новый механизм:** отгрузкой считается волна, владеющая ОТГРУЖАЮЩЕЙ (последней) стадией — `backend/internal/pipeline/snapshot.go:243`=`finalStageWave is the wave that owns the SHIPPING (last) stage`; на редакторском конвейере это edit, на черновом-только — draft. Проверять надо ИМ, иначе черновой-только конвейер получит ось, которая никогда ничего не считает отгруженным (предложено движковой сессией при сдаче, сверено мной по коду) | бэкенд | скоро | Читающий метод стора + перевод оси на факт отгрузки; отдельный пак | приёмка D39.170 | +| 233 | **Трата терминолога вне объёмного потолка масштабируется КНИГОЙ, а не грантом** (D39.170). Замер: три последовательные покупки по одному юниту на четырёхглавной книге дали три полнокнижных консолидации по $0.005460 каждая — покупка одного юнита обходится в ~1.5× стоимости самого юнита. Книга на 500 юнитов, проданная по одному, оплатит 500 полнокнижных проходов. Место траты — в ЦЕНЕ, а не в потолке (решение подтверждено), но при мелкой нарезке продажи она перестаёт быть накладной и становится основной статьёй: это ВХОД В КАЛИБРОВКУ ЦЕНЫ, а не сноска | бэкенд | скоро | Учесть в модели цены при следующей калибровке; либо чекпойнт консолидации, переживающий покупку | приёмка D39.170 | +| 237 | **Два загейченных триггера НАЖАТЫ и не отработаны** (реестр `13-tech-debt-anchors.md` §Б-108, сверено 30.08). **(а) `go.work`:** условие «появление Go-кода платформы» выполнено давно — `platform/go.mod` есть, `ls go.work` в корне даёт «No such file or directory». Ратифицировано D39.85 §8 п.4 (`docs/research/23-engine-platform-seam.md:66` = `go.work — коммитить, когда у платформы появится Go-код`); цена — один файл, по тому же §6 он решает только dev-удобство и не меняет ни видимости, ни версий. **(б) вендор-сверка маппинга эффорта `deepseek-v4-pro`:** вахта D39.92 сработала 13.08 changelog'ом вендора. ⚠ **Испр. 05.09: НОСИТЕЛИ БОЛЬШЕ НЕ ПРОТИВОРЕЧАТ** — и квирки (`docs/experiments/00-provider-quirks.md` §3г), и `STACK.md` говорят одно: ручка ДОХОДИТ до модели. Прежняя редакция обвиняла оба носителя в утверждении «ручки у pro НЕТ», которого ни один из них уже не несёт, и это заставляло сессию искать спор, которого нет. Живой остаток — вендор-сверка САМОГО МАППИНГА и величина эффекта, и по гардрейлу владельца это закрывается ТОЛЬКО вендор-докой, а не выбором стороны. Держит жильца Д5 и калибровку цены редакторского арма. ⚠ **Класс важнее двух пунктов: спроектированный механизм без носителя события тихо становится долгом, и никто не проверяет, не нажат ли спусковой крючок.** | оркестратор | скоро | (а) один файл в корень; (б) заказ полигону на вендор-сверку | аудит очереди 30.08 | +| 241 | **Канон противоречит сам себе на ДОЧИТАННОЙ книге, и принятая правка банка умирает молча** (названо телом D39.165 §3 28.08, носителя не получило; заведено оркестратором №20 30.08 по находке сессии P12). Две фразы: правка банка «takes effect on the NEXT run» (`docs/architecture/14-api-contract/openapi.yaml:511`=`takes effect on the NEXT run`) против «finished work is not bought twice» + подъём потолка только у ПРИОСТАНОВЛЕННОЙ книги (`:590`=`finished work is not bought twice`). У дочитанной книги следующего прогона купить нечем: пользователь правит банк, получает квитанцию об успехе — и правка не доезжает ни до одной строки никогда. ⚠ Смежное лечение уже существует и не связано с этой дырой: пере-проход ПОКУПАЕТСЯ членом `RunRequest.re_pass` (канон 0.7.0, D39.166) — то есть механизм есть, а фраза канона его не признаёт для дочитанной книги. Решать формой: либо канон признаёт пере-проход входом для дочитанной книги, либо дверь правок отказывает такой книге ЧЕСТНО вместо ложной квитанции | контракт (+платформа) | скоро (следующее касание контракта) | контрактный минор + пин на дочитанной книге | D39.165 §3, эррата 30.08-б, находка сессии P12 | +| 242 | **Реестр D-нот: колонки «статус» и «тело» разъехались на 74 строках из 224** (замер аудита доков 30.08). У свежих нот в «статусе» стоит заметка «ЖИВОЕ: …», а слово `жив` уехало в «тело»; шапка таблицы описывает другой порядок. Гейт `counts.py --check` этот класс НЕ ловит по устройству (сверяет полноту номеров, не форму ячеек). Лечение — не ручная перекладка (дороже пользы и легко внести новую ложь), а машинное: правило формы в `counts.py` + разовый прогон приведения. Пока не сделано — в легенде реестра стоит правило чтения (испр. 30.08) | оркестратор | когда-нибудь | правило в `counts.py` + разовое приведение | аудит доков 30.08 | +| 243 | **Остаток аудита доков 30–31.08: 19 удержанных находок НЕ применены** (аудит — 5 линз + верификатор на каждую, 57 находок, 55 удержаны, 36 применены сменой №20). Перечень: ~~**arch-3**~~ **ЗАКРЫТ 31.08 — разбор телом D39.179 п.5** (был вдвое больше заявленного: 51 указатель вместо 13, и дороже адресов оказались ЛОЖНЫЕ КЛЕЙМЫ) · **arch-5** (правило языка знает две корзины, `reader.txt` — третья) · **arch-7** (§2 закона шва: дисциплина флока не описывает новый глагол-писатель) · **arch-9** (реестр загейченных триггеров не знает нажатых 30.08) · ~~**arch-10**~~ и ~~**arch-11**~~ **ЗАКРЫТЫ 02.09** (числа словаря событий сняты в пользу кода; отвергнутый ключ назван отвергнутым) · **arch-12** (шапка `09-target` сама зовёт себя неполной — строку под таблицей слоёв надо внести; ⚠ ЖИВ на 02.09: греп `D39.181` по `docs/architecture/09-target-architecture.md` — 0 хитов, греп `D39.182` — 0 хитов, то есть лендинги 31.08 в док слоёв не внесены) · **contract-8** (эррата 15.08-в в шапке D-лога указывает на промт, уехавший в архив) · **contract-10** (`Export.failure_code` «becomes an enum with the first built format» — формат построен, условие наступило) · **progress-6/7/8/10/11/12/13/14/15** (мелочь CURRENT-STATE и строк бэклога: протухшие «запушена»/«строка 200»/якорь `miner_emit.go`/дубль 238 внутри 160 и пр.). ⚠ Отчёт аудита жил в песочнице сессии №20 и умирает с ней — здесь ЕДИНСТВЕННЫЙ носитель списка; воспроизведение = повторный аудит (5 агентов, ~2 часа) | оркестратор | скоро | пройти списком | аудит доков 30–31.08, сдача смены №20 | +| 244 | **Гейт якорей на пре-коммите ломается всякий раз, когда зона правит КОД и СВОЙ реестр одним незакоммиченным деревом** — и врёт в обе стороны. Механика: хук судит ЗАКОММИЧЕННЫЙ док против РАБОЧЕГО кода, поэтому пере-нацеленные, но не залёнджённые якоря читаются как битые. Замерено на приёмке P12 31.08: у оркестратора хук напечатал 13 битых якорей `platform/docs/DEFECT_REGISTER.md`, у зоны `counts.py --lint` на том же дереве дал **0**; права зона — в HEAD `internal/runs/runs.go:323`, в рабочем `:347`, и токен по новому адресу на месте. ⚠ Обратная сторона опаснее и не замерена: якорь, ставший битым ПО-НАСТОЯЩЕМУ, тем же механизмом может оказаться зелёным. Свойство общее, не про этот пак | оркестратор | когда-нибудь | либо судить обе стороны из одного состояния (`--from-index` уже есть — проверить, покрывает ли он случай), либо печатать, что сравниваются РАЗНЫЕ состояния | приёмка P12 оркестратором №21, 31.08, разрешено командой | +| 245 | **Pathspec-форма коммита молча роняет UNTRACKED-файлы, и сломанный коммит выглядит нормальным до первого чужого прогона.** `git commit -- <пути>` обходит ИНДЕКС и берёт рабочее дерево только для ОТСЛЕЖИВАЕМЫХ путей: предварительный `git add` нового файла она игнорирует. Поймано на лендинге P12 31.08 — коммит `e1cb692` унёс `migrations.sha256`, уже ссылавшийся на три миграции, а сами миграции 00029/00030/00031 и три теста остались снаружи; починено амендом секундного неопубликованного коммита при пустом индексе (`0a680a3`). ⚠ Канон git-координации в `CLAUDE.md` объясняет про pathspec ТОЛЬКО то, что она не трогает чужой индекс — то есть учит половине правды и ровно этим создаёт ловушку. Норма, которую предлагаю вписать: новые файлы стейджить явно и проверять состав `git show --name-only`, а не доверять форме. ⚠ **ПОЛОВИНА ПОСТРОЕНА 31.08** (`94381bb`, испр. 02.09): в `docs/scripts/githooks/pre-commit` стоит warn-блок, который перед каждым коммитом печатает неотслеживаемые файлы в каталогах коммита. Живой остаток — блок ПРЕДУПРЕЖДАЕТ, но не блокирует, и на свежем клоне хук вообще не установлен (строка 220) | оркестратор | скоро (решение владельца — его канон) | одна строка в `CLAUDE.md` §«Git-координация мультисессий»; вписывает владелец или оркестратор по его слову | лендинг P12 оркестратором №21, 31.08 | +| 247 | **§2.2 закона раскрытия опровергает себя следующей же строкой — эррата зонного дока.** Формальная фраза требует «держит ОБА операнда сравнения и обязано их НАПЕЧАТАТЬ», а её собственный пример тут же говорит обратное: честная форма — НАЗВАТЬ ОСЬ («снапшот разошёлся» честно, «конфиг/промпты изменились» ложно). ⚠ **Ратифицированный текст D39.181 п.1 требования «напечатать» НЕ СОДЕРЖИТ ВОВСЕ** — оно живёт только в `backend/docs/DISCLOSURE_LAW_DESIGN.md`, значит противоречия с ратификацией нет и решает ЗОНА, не владелец. ⚠ Довод «граница прячет имена моделей и хеши» ОПРОВЕРГНУТ исполнением: эти значения уже едут по тому же stderr штатным INFO-логом, включая `memory_version=<12 hex>` — значение того самого поля. Цена бездействия на живых данных = НОЛЬ (единственная сдвинувшаяся ось — хешевая, печать дала бы две несравнимые строки SHA) | бэкенд | когда-нибудь | эррата к §2.2: операнды называются осью, а не значением | приёмка D39.182 + разведка оркестратора 31.08 | +| 248 | **Полнота самообъявления о правках чужих тестов ничем не проверяется — и трижды оказалась неполной.** P11 назвала файл, которого не трогала; P12 не назвала тест, у которого переписаны ОБА утверждения; сессия пака «деньги и честность» в первой редакции комментария утверждала неверное о силе собственной правки. ⚠ **Мой метод проверки был слабее, чем я его подал:** греп `^[-+].*t\.(Error|Fatal)` ловит строку СООБЩЕНИЯ, а утверждение — это строка СРАВНЕНИЯ, и она другая (замер: греп локализует утверждение в 1 случае из 475). Предложение разведки: warn-only гейт-детектор при лендинге — список пред-существующих тестов с изменёнными строками утвержденческой формы ВНУТРИ пред-существующих тел; прототип ~25 строк sh прогнан на двух лендингах и указал ровно на `bankfixpack_test.go`. Площадка есть — `docs/scripts/githooks/pre-commit` уже warn-only. ⚠ Ложняки измерены: целиком новый `t.Run` внутри старого `func` даёт срабатывание (1 из 6 на P12) | оркестратор | скоро | гейт-детектор warn-only + пункт чек-листа приёмки | разведка оркестратора 31.08 по вопросу владельца | +| 249 | ⚠ *(пример в теле ниже ссылается на ряд PD-246 — он ЗАКРЫТ D39.194; пример держим как археологию класса, живым рядом его не читать)* **Девять рядов бэклога потеряли слово веса, и гейт на них НЕ краснеет.** ⚠ **Лечение ПОСТРОЕНО (сверено кодом 02.09): вес судится ПРЕФИКСОМ ячейки** — `docs/scripts/counts.py`, греп `BACKLOG_WEIGHTS` (три слова: «блокер-очереди» · «скоро» · «когда-нибудь»), и «скоро» считается тем же префиксом. Этим убита ВТОРАЯ половина класса: подстрока ловила слово в ПРОЗЕ, и фраза «переведена из «скоро»» ре-добавляла ряд в счёт — число скакнуло **53 → 56** при одной новой строке (замер 02.09, пере-счёт скриптом). ⚠ Гейт рождён ЗЕЛЁНЫМ, а не красным: девять известных рядов внесены «дедовщиной» — греп `WEIGHT_GRANDFATHERED` там же, ряды **5 · 13б · 94 · 96 · 97 · 149 · 205 · 221 · 246**. **ЖИВОЙ ОСТАТОК — сами ячейки:** у 96/97 прочерк ЗАКОНЕН (надгробия строк, уехавших в зонный бэклог, D39.84), остальные семь потеряли вес молча и чинятся оркестратором — каждая починенная выходит из списка дедовщины. ⚠ Два ряда шире класса: **149** («исполнен и заленден 10.08») и **205** («сделано 21.08») объявляют себя ИСПОЛНЕННЫМИ прямо в колонке веса, хотя по правилу таблицы закрытые строки в ней не живут — это либо живой остаток без веса, либо непойманный класс C; **246** несёт самодельное «СРОЧНО», которого в словаре нет. | оркестратор | скоро ($0, гигиена трекера) | правка семи ячеек → выход из `WEIGHT_GRANDFATHERED` | ревизия доков 02.09, приёмка контролёра | +| 217 | ⚠ **ЛИД ПРЕУВЕЛИЧЕН — испр. 05.09:** «не работают вовсе / блокирует любой прогон» ложно — пользователь `ubuntu`, литерал пути РАЗРЕШАЕТСЯ, полигон покупал 30.08–02.09. Живой долг — сам захардкоженный путь, а не блокировка. **Скрипты полигона захардкодили АБСОЛЮТНЫЕ пути двух корней и не работают на этой машине вовсе.** ДВА РАЗНЫХ слома. **Корень репо** — смена пользователя: литерал в 121 файле, из них 104 дословно `REPO = Path("/home/ubuntu/projects/textmachine")`, портабельных форм всего 5. **Корень книг** — оба события порознь: литерал `/home/ubuntu/books` 86 файлов (пользователь), портабельный `Path.home()/"books"` 89 файлов (переезд каталога; на прежних машинах работал). Объединение 173 файла. Пользователь теперь `ubuntu-26`, книги переехали в `<репозиторий>/books` ⇒ ломается и то и другое, включая ЖИВОЙ гейт фазы Д `eval/conformance.py:49`=`REPO = Path("/home/ubuntu/projects/textmachine")`. Живых носителей 26 по корню книг (среди них портабельная форма преобладает 20:6) плюс корневые гейты и сборщики корпусов; остальное — скрипты закрытых эксп-12–16, их владелец велел ВЫБРОСИТЬ, а не чинить (D39.157 п.4а). Форма правки — за зоной; приор оркестратора: один модуль путей, корень резолвится МАРКЕРОМ вверх по дереву (движок так и делает — `backend/internal/miner/miner_parity_test.go:29`=`derived from the repository MARKER`), книги от него, обе ручки перекрываются env | полигон | скоро (блокирует любой прогон зоны) | пак путей полигона | переезд машины 24.08, №19 | +| 219 | **Line-якоря в тела D-лога обречены съезжать, и механизм именно в дисциплине эррат.** Эрраты вписываются в КАРТУ ШАПКИ (append-only, D23.3), то есть в начало файла, — значит каждая эррата сдвигает номера строк ВСЕХ тел ниже, и любой якорь вида `05-decisions-log.md:NNN` умирает молча. ⚠ Замерено на себе 27.08: три эрраты за сессию убили якоря в `docs/architecture/17-seam-inbound-law.md` (греп `Эррата, которую ратифицирующая нота обязана поставить`) и `docs/research/25-seam-cold-review.md:5`=`адресуем НОМЕРОМ, а не строкой` (оба целили в `:232`, тело уехало на `:239`; ⚠ 02.09 обе площадки уже переведены на форму номера ноты — прежний голый указатель `17-seam-inbound-law.md:120` показывает пустую строку). Лечение — не пере-нацеливание (оно повторится через эррату), а СМЕНА ФОРМЫ якоря: в тела D-лога целиться номером ноты (`^## D39.106`), который стабилен навсегда, а не строкой. ⚠ **Первая половина лекарства ПОСТРОЕНА:** `counts.py --lint` сверяет якоря в тела D-лога СТРУКТУРНО и без токена — владелец целевой строки (ближайший `^## D<номер>`) обязан совпасть с номером, названным рядом; остаётся перевести живые якоря на форму номера | оркестратор | скоро (растёт с каждой эрратой) | `--lint` учит форму `файл:^## D<номер>`, живые якоря в D-лог переводятся на неё | ревью доков 24.08, механизм и отсутствие носителя — 27.08, D39.160 | +| 220 | **Репо-широкий гейт доков бутстрапится пакетным менеджером ОДНОЙ зоны, и та заморожена.** Диспетчер `.git/hooks/pre-commit` зоно-нейтрален по построению (`for hook in */scripts/githooks/pre-commit`, `#!/bin/sh`, node не нужен) и судит `CLAUDE.md` + `docs/**` + `platform/docs/**` + `frontend/docs/**` (`docs/scripts/counts.py:569`=`ROOT / "CLAUDE.md"`), но единственный его УСТАНОВЩИК — `frontend/scripts/githooks/install.mjs`, вызываемый ключом `prepare` из `frontend/package.json`. Охват и бутстрап не совпадают ⇒ инструмент решает свою задачу не в полной мере. Проверено исполнением 24.08: на этой машине `.git/hooks/` содержал только `*.sample`, гейт МОЛЧАЛ, ничего не проверив, и поймал первые четыре дефекта только после ручной установки; сессия бэкенда или доков `npm install` не делает никогда. Приор: зоно-нейтральный установщик в `docs/scripts/githooks/` как ЕДИНСТВЕННЫЙ писатель диспетчера, `prepare` фронта зовёт его — фронтовая половина выписана пингом №19 в зонный журнал фронта. ⚠ Ручная установка — временная мера, пока строка открыта; записывать её как порядок работы ЗАПРЕЩЕНО (это ровно тот обход, цену которого называет шапка `CLAUDE.md`) | доки + фронт | скоро | зоно-нейтральный бутстрап + правка `prepare` при разморозке | аудит переезда 24.08, №19 | +| 49 | **Этапы Б+В спеки D15.2** (content-addressed resume / `guard_hash` — D39.31 сознательно не строил) ; этап В = tmctl export-контракт D29.1 (annot-v1 · цвет-мап+rollup · политика красных fail-closed) + операторский протокол-документ релиза гендер-твиста (D5.1): сам механизм УЖЕ построен — until_ch-правка → точечный re-edit со сметой и $0-пере-пином (`repin.go`/`rebill.go`, D39.42 п.5/D39.45) | бэкенд | скоро (ПОДТЯНУТА D39.81: annot-v1 = источник замечаний для фронта — критический путь подключения) | отдельное решение (annot-половина — по контракту 14, D39.99) | D39.34(4), D33 п.5, D39.81 | +| 49а | **ALTER-шаги миграций v8–v14 не идемпотентны вопреки шапке `migrate.go:9-11`** (полу-применённая БД не сходится; счётчик версий скрывает) — находка критика полноты пака-19 | бэкенд | когда-нибудь | отдельное решение | D39.56, PACK19_BUILD §6.9 | +| 50 | F3-остаток идемпотентности | бэкенд | когда-нибудь | отдельное решение | D39.34(4) | +| 51 | `human_override` LOCK (D29 п.1г, в коде 0 вхождений) | бэкенд | когда-нибудь | отдельное решение | D39.34(4) | +| 52 | **Ф2-гейты вне идеала**: морфо-гейты канцелярита + L1-лемматизация (python-сайдкар) · полный OpenCC · опциональный пре-перевод гейт ; состав явно: канцелярит + РОД (строка 82) + класс Ф2-гейтов карты 04-unhappy (обсцен-гейт/феминитивы/время сцены — состав решить паком) ; + класс идиоматики (свип-хвост, D39.73): сехоуюй-словарь · вэньянь-классификатор (zh) · васэй-эйго ложные друзья (к ja-паку 81) — данные пары или закрытие «банк книги покрывает» тем же паком | бэкенд | когда-нибудь | отдельное решение | D39.34(4) | +| 54 | Масштаб целой книги: волны/каденс/потолки/ETA на сотнях глав (гоняли максимум 10; книга 7,78 млн симв., ~2284 раздела). ⚠ **Дописка инвентаря №18 (D39.147 п.2г):** жёстких потолков размера в коде НЕТ, но исходник читается в память целиком (`chunk/ingest.go:98`), чтения стора беспагинационны под `opTimeout = 10s` (`store/store.go:39`) и бюджеты нарезки калиброваны на 25 главах (`config/pipeline.go:126-138`) — ни одно из трёх на 2283 главах не проверено ничем | бэкенд | когда-нибудь (последним по курсу) | МАСШТАБ | D39.33, CURRENT-STATE | +| **— ПОЛИГОН (кандидаты пакетов) —** | | | | | | +| 55 | **`dialogue_dash` мерить только на невиданном тексте** (подогнан под 蛊真人; цифры мини-прогона аргументом не считаются) ; расширено до вне-претрейн чекпоинта целиком: r-коэффициенты exp01/08 · precision чекеров · частота эха · чистовик exp15-выводов ; + arity-полоса паспорта (D29.2г): решить — dialogue_dash покрывает диалоговую половину или мерить (D39.73). **Частично закрыта эксп-21 (D39.117):** направление главного вывода воспроизведено на чистом en-материале (узнавание 1/5), $0-довесок исполнен частично; ⚠ **ПЕРЕ-СНЯТА 05.09 (D39.198 п.5): требования НОВОЙ книги здесь НЕТ.** Владелец: прогоняем на тех же текстах (мастер Гу и Жан-Кристоф), а «известность модели по претрейну» остаётся ОГРАНИЧЕНИЕМ ВЫВОДА — результат на классике читается как предварительный, и это пишется в вывод, а не покупается новой книгой. Прежняя редакция несла ЖЁСТКИЙ платный заказ полигону. **срез эксп-21 НЕ купил** (главный zh-замер на книге 4/5, без пинга) — остаток = **ОГОВОРКА В ВЫВОДЕ**, а не покупка: замер идёт на мастере Гу и Жан-Кристофе, а «модель знает текст по претрейну» пишется ограничением результата (⚠ испр. 05.09 — колонки продолжали заказывать неконтаминированный zh-срез уже ПОСЛЕ того, как шапка строки его сняла: полигон читает колонки) | полигон | когда-нибудь (оговорка вывода, не заказ) | формулировка в отчёте | D39.37(4), D39.40, D39.46, D39.108, **D39.117** | +| 56 | Ёфикатор/санитайзер-классы не размечены (§6.5 отчёта пакета-6) | полигон | когда-нибудь | полигон-пакет | D39.46, CURRENT-STATE | +| 57 | Пере-замер «контексты — главный рычаг» на трудной выборке пакета-7 с боевой сборкой (до него kwic-веса/семантику не трогать; перф-хвост AttachKWIC — строка 37: фикс-пак 128 закрыт D39.118, опция в нём не взята, семантика не менялась) — напряжение с D39.46 названо, не отменено | полигон | когда-нибудь | полигон-пакет | D39.50, D39.118 | +| 58 | **Не покрыто пакетом-8**: вторая книга/пара/модель · строка `drafts:` · ось `batch_runes` · разметчики-модели (не люди) · precision роли на «расширенном, но осмысленном» материале ; + контрастивный регрессионный сьют по каталогам режимов отказа (12-*) · чистовик exp15-выводов | полигон | когда-нибудь | полигон-пакет | POLYGON_PREMEASURE §1.8/§2.5/§3.5/§7.6 | +| 59 | **Вендор-чек префикс-кэша ZAI/GLM** (на нём стоит вся кэш-экономика W1/Q2c) ; + GLM context-overflow гард (finish=model_context_window_exceeded — NOT-do пака-12 без решения) ; + Mistral-strip гейт message-builder (research/21 §1.1: extra_forbidden на reasoning-поля; ЛАТЕНТЕН при нашем single-shot wire — гейт перед прод-путём mistral в канале B / любым multi-turn; D39.74) | полигон | когда-нибудь (до МАСШТАБА) | полигон-пакет | D39.34(6) | +| 60 | Scheduler-aware волны под peak-valley DeepSeek (прямой COGS-рычаг) | полигон/бэкенд | когда-нибудь (до МАСШТАБА) | отдельное решение | D39.34(6) | +| 61 | **Прайс/wire-гигиена**: продление `prices_checked` без правки чисел · гейтнутые платные армы (edit-единица >3200 и др.) · wire-probe temperature в thinking-канале DeepSeek | полигон | когда-нибудь | полигон-пакет | D39.34(6) | +| **— Ф2.5 / ПИЛОТ / ПРОД —** | | | | | | +| 62 | Билингв-якорь (D25 п.9 Q1) | владелец | когда-нибудь | Ф2.5 | D25 п.9, CURRENT-STATE | +| 63 | Контаминация корпуса (D27 п.4) | владелец/полигон | когда-нибудь | Ф2.5 | D27 п.4, CURRENT-STATE | +| 64 | Судья-дублёр (D22.6) | бэкенд | когда-нибудь | Ф2.5 | D22.6, CURRENT-STATE | +| 66 | Пилотные D25-гейты: publishable/waiver (п.1) · FN-bound L3 (п.4) | владелец | когда-нибудь | Ф2.5 | D25, CURRENT-STATE | +| 67 | **Прод-гигиена: юр-пакет · провенанс 12-*-доков · xAI-ключ off перед продом** (D27) ; + юрисдикционные annex-ре-чеки при новых рынках (D39.29) + поле «версия исходника» book.yaml на интейке (04-unhappy §5) | владелец | когда-нибудь | Ф2.5 | D27, CURRENT-STATE | +| 68 | Residual-тачпойнты exp16, не влитые в сид-дельту: мини-голд алиасов (ОТЛОЖЕН до первого длинного прогона — D39.103) · precision@30 (`books/gu-zhenren/exp16/`) | полигон | когда-нибудь | Ф2.5 / полигон-пакет | CURRENT-STATE | +| **— Ф3 / ПРОДУКТ —** | | | | | | +| 69 | Gemini API «под-18» обязательство на конечный продукт (независимо от лейблов) | владелец | когда-нибудь | Ф3 / отдельное решение | D39.32, D39.34(7) | +| 70 | Action-security gate перед выдачей tools/webfetch (D25 п.5) | бэкенд | когда-нибудь | Ф3 | D39.34(7) | +| 71 | **Планы research/22**: epub-tag-rewrite · Q7-леджер ; + F3-brief из D29 п.3 (chat-edit · Not-useful-петля · cost-of-fix) + Ф3-скоуп 02-mvp-plan (TMX/TBX · Bertalign · дистилляция 7–14B); + V5: фронт ВЕБ-ПЕРВЫЙ, SEO/ранжирование (куки · страницы-сироты · актуальные алгоритмы Google) — определяет выбор фреймворка (SSR vs SPA), в Ф3-дизайн ДО выбора стека (ПТ-23) | бэкенд | когда-нибудь | Ф3 | D39.34(7), START_PROMT V5, D39.80 | +| 94 | **Продукт-механика входа и прогона** (V2, ПТ-16..18): абьюз/misuse-прескрин дёшево и точно ДО трат токенов (H8) + UI-контракт отказа (проект-решение D39.80) · лимит размера входа настройкой (H7) · продукт-кнопки «стоп/продолжить» поверх построенных graceful stop и redrive, абьюзивный прогон НЕ продолжать (H10); API-форма — по контракту 0.3.0 (отказ прескрина РЕШЁН: `rejected` + грубый `content_refused`, К-9 закрыт D39.138 п.2б) | бэкенд | к подключению фронта (ПОДТЯНУТА D39.81; лимит можно раньше, к пилоту) | отдельный пак при Ф3-препе (контракт 14 ратифицирован) | START_PROMT V2, H7/H8/H10, D39.80, D39.81 | +| 96 | **→ переехала в `platform/BACKLOG.md` П-1** (зонные бэклоги, D39.84: HTTP/SSE-слой, обвязка, аутентификация, порядок деплоя); здесь остаётся ратифицированным сам ИНВАРИАНТ D39.81 — движок = процесс-на-прогон (EXCLUSIVE flock `store.go:43`), сервер в backend НЕ пишется | платформа | — | зонный бэклог | D39.81, D39.84 | +| 97 | **→ переехала в `platform/BACKLOG.md` П-2** (глобальный брокер рейт-лимитов; гейт «до второго параллельного пользователя» зафиксирован там же) | платформа | — | зонный бэклог | D39.81, D39.84 | +| 127 | **Устаревший DDL-коммент `glossary.source`** (`migrate.go:194`: «seed|ruby|auto», фактические пути записи — seed/ruby/mined, `auto` не пишет никто; фантом уже утёк во фронт-доки дважды) — поправить коммент | бэкенд | когда-нибудь (попутно любым паком store) | однострочная правка | ревью контракта 04.08, D39.99 | +| 106 | **Слой 3: целевой контракт «узкие мандаты + ДИФФЫ» против текущего full-regen — гейт «перепроверить до стройки» в силе, приоритет ПОНИЖЕН (D39.117: full-regen выигрывает у ремонта; оговорка полигона — чинил дешёвый фиксер по предложению, не сильный редактор узким мандатом).** Реактивация — только через эту строку. Археология дословно (эмпирика D39.108 · история дыры учёта) — `architecture/13-tech-debt-anchors.md` §Б-106 | владелец → бэкенд | когда-нибудь (пере-проверка «сильный редактор × узкий мандат» — перед стройкой слоя 3) | замер → решение владельца | 09 §Слой 3, D39.90, D39.108, **D39.117** | +| 114 | **Конфиго-слой ручки эффорта: два дешёвых хвоста приёмки (вне снапшота, $0 прогонов).** (а) **Д4 отчёта:** `gates.terminology.target_script` НЕ сверяется с `book.target_lang` — `target_lang: ru` + `target_script: Latin` грузится чисто и **ИНВЕРТИРУЕТ** банковский экран (ловит целевой, пропускает чужой); сверка при загрузке против `lang.LangScripts(TargetLang)` — тот же дата-план, что у экрана строки 46, громкий отказ на несовпадении. (б) **Находка-2 приёмки:** стейл-доккоммент `capability.go:78` — у константы `ReasoningExtraBodyDisable` до сих пор «effort "" leaves the provider default», противореча проводу (`applyToBody` мержит disable на `""`, комментарий в теле arm это прямо объясняет) и починенному `ThinksOnWire`; однострочник тем же касанием | бэкенд | скоро (мелкий пак или попутно со строкой 46) | правка Go, снапшот не двигает | D39.91, EFFORT_HANDLE Д4 | +| 115 | **`//go:embed` целевых данных — ЯВНЫЙ список файлов: новая ЦЕЛЬ требует правки Go (Д6 отчёта).** `internal/lang/embedded.go:22` перечисляет файлы поимённо, `CompileCheckers` паникует при неполном файле цели ⇒ на канон-вопрос «заработает ли пара, которой в репо НЕТ, без правки Go» ответ сегодня **НЕТ** — дыра в ратифицированной «ФАЗЕ 2 ОБЩНОСТИ ✅» (D39.64), и она не про язык, а про строку эмбеда. Решить форму: `embed data/*` (и как манифест фолдится в `EmbeddedVersion`, чтобы НЕ перекупать чужие пары) против явного списка как осознанного гейта полноты данных цели | оркестратор → бэкенд | когда-нибудь (триггер: первая новая целевая пара; учтён в реестре 108) | отдельное решение | D39.91, EFFORT_HANDLE Д6, D39.64 | +| 108 | **Реестр ЗАГЕЙЧЕННЫХ ТРИГГЕРОВ (триггер → что вернётся → источник) — ВЫСЕЛЕН ДОСЛОВНО в `architecture/13-tech-debt-anchors.md` §Б-108; сверять на каждом переходе горизонта (норма D39.66 «каждое отложено получает носитель» в силе).** ⚠ Живое оттуда: go.work-триггер УЖЕ наступил (`platform/go.mod` заведён) — ⚠ **тот же факт несёт строка 237(а), испр. 05.09: чинится ОДИН раз и там, здесь он ЗАПИСЬ РЕЕСТРА, а не заказ** · вахта маппинга эффорта dspro «early August 2026» · движение тулчейна к go1.27 ⇒ строка 119 ПЕРВОЙ | оркестратор | скоро ($0, гигиена трекера) | завести реестр + сверку в норму лендинга | D39.66, D39.90 | +| 109 | **Продуктовые требования без строки-носителя: ПТ-6 (структура абзацев) · ПТ-7 (слабый оригинал — вопрос владельца) · ПТ-22 (продуктовый интейк настроек) · ПТ-10 (механизм веб-фетча).** Носители заводить при первом касании тем; реестр `product-requirements.md` первичен. Разбор дословно — `architecture/13-tech-debt-anchors.md` §Б-109 | оркестратор/владелец | скоро ($0 — расписать носители) | завести строки/вопросы → диспозиции | D39.90, product-requirements | +| 110 | **Детектор повторов лемм / защита авторских рефренов** (`04-unhappy-paths.md:97,130 п.5`): $0-минимум исполнен промптом (editor.md, пакет-чекеров 02.08), механизм явно не строился — «нет размеченного класса; связка с alignment/Bertalign». Строки-носителя не было; предмет живой, потому что отличить дефектный повтор от авторского рефрена без выравнивания нельзя | бэкенд/полигон | когда-нибудь (с корпусом пилота, строка 85) | размеченный класс → решение | 04-unhappy §5, D39.90 | +| 111 | **Дубль ключа пар-файла: фикс накрыл половину.** D39.82 закрыл строку 53 через `putUniqueDC` в `parseDCCheckers`, но генерик-парсер категорий `parseCategoryRows` (`internal/lang/langpack.go:806-826`, строка `cats[f[0]][f[1]] = val`) по-прежнему МОЛЧА last-wins — а якорь техдолга указывал именно на него. Пар-данные с опечаткой-дублем тихо теряют первую строку | бэкенд | когда-нибудь (малое касание, с любой правкой langpack) | fail-loud + тест | 13-tech-debt-anchors, D39.82, D39.90 | +| 118 | **tools/go.mod — РЕШЕНИЕ ПРИНЯТО (D39.97 п.4): строить отдельным малым паком.** `cmd/tmvet`+`internal/archguard` → отдельный модуль (`backend/tools/`); `make battery` гоняет оба модуля; `tool`-директива Go 1.24 НЕ решает (MVS общий). Выигрыш: бамп инструментов физически не двигает x/net/x/text. Sqlite 1.55 остаётся (D39.97 п.4) | бэкенд | скоро (до следующего бампа зависимостей) | малый пак по D39.97 п.4 | D39.96 п.6, D39.97 | +| 119 | **x/text-детерминизм: вердикт-несущие вызовы НЕ свёрнуты в версии (находки-5/6 приёмки).** `SanitizerVersion` не сворачивает ничего x/text-ного, а `detectCJKLeak` зависит от `width.Fold` (`sanitizer.go:211,687`) — смена x/text перевернула бы вердикт БЕЗ смены снапшота; `ExportNormalize` меняет экспортные байты вне хешей (`sanitizer.go:709`); `xTextVersion` пинит строку go.mod, НЕ скомпилированные таблицы — тулчейн go1.27 переключит x/text на Unicode 17.0.0 МОЛЧА (`tables17.0.0.go //go:build go1.27`; жилец реестра 108). Делать: явные версии-свёртки + механическую сверку «таблицы↔константа» вместо совпадения | бэкенд | скоро | правка версий-свёрток + тест | D39.96 п.6, отчёт §5 находки-5/6 | +| 120 | ⚠ **ЛИД УКАЗЫВАЕТ НА НЕСУЩЕСТВУЮЩУЮ ФУНКЦИЮ — испр. 05.09:** продового `buildCheckers` нет (`grep -rn 'buildCheckers' backend --include=*.go` → только тест-хелпер), и `lang.Load(` вне тестов не вызывается вовсе. Класс «бейзлайны ключуются по классу, не по паре» может быть жив — но искать его надо не здесь. ⚠ **Где искать (пере-снято 05.09): единственный прод-носитель бейзлайнов сегодня — `backend/internal/config/models.go`, и ключуются они по KIND ПРОВАЙДЕРА, а не по паре;** пара-специфика чекеров живёт данными `internal/lang`. ⇒ строка держится как ревью-вопрос общности («заработает ли пара, которой в репо НЕТ»), а не как известный адрес правки: **прежде чем строить — предъявить дефект на паре, которой нет.** **`buildCheckers` жёстко берёт `lang.Load(root,"zh","ru")`, бейзлайны ключуются по классу, не по паре (§7-8) — приезд ja-ru требует правки Go, против мандата общности §0.1.** Родня строки 115 (явный embed-список целей) — брать одним касанием | бэкенд | скоро | правка Go + тест на паре-которой-нет | D39.96 п.6, отчёт §7-8 | +| 121 | **archguard v2 — остаток (б)/(в)/(г)/(д); (0а)/(0б)/(а) ЗАКРЫТЫ дофиксом D39.97.** Полный фикс-лист посадок приёмки D39.96 с file:line — дословно в `architecture/13-tech-debt-anchors.md` §Б-121 | бэкенд | скоро (остаток: (б) тип вместо свитча · (в) build-теги · (г) 4-й анализатор · (д) семь пропусков) | правка анализатора + посадки | D39.96 п.2/п.6, отчёт §7-9/12/13 | +| 122 | **Гигиена пака стандартов — 11 микро-пунктов, не-блокеры приёмки (D39.96/97).** Полный список дословно — `architecture/13-tech-debt-anchors.md` §Б-122 | бэкенд | когда-нибудь | мелкие правки | D39.96 п.6, отчёт §7-6/7, §9 хвост | +| 123 | **Полигон: `jieba==0.42.1` — build-time зависимость артефакта контраста `eval/exp16/data/jieba_dict_general_zh.txt`** (пере-собран бэкенд-сессией 03.08, полный sha256 сошёлся с пином `16-bank-mining.md`); дописать в манифест окружения полигона с пометкой «build-time, не runtime» | полигон | когда-нибудь | строка манифеста | D39.96 п.6, отчёт §7-4/§6 | +| 124 | **Калибровка снапшота (вопрос владельца 04.08, разбор D39.97 п.5): нацеленность, не агрессивность.** ⚠ **Осей теперь ЧЕТЫРЕ — дописка D39.151:** (г) **идентичность оплаченной работы** («строка диспозиции ↔ вызовы, которые её оплатили») — переселена сюда из строки 195 решением владельца 17.08; родня оси (в), потому что массовое кросс-снапшотное переиспользование подрывает наивную атрибуцию по равенству снапшота; смежный носитель — §7 спеки D15.2. Прежние три оси одним дизайн-паком: (а) недо-чувствительность — вердикт-несущие вызовы x/text не свёрнуты (вход: строка 119); (б) пере-охват — `EmbeddedVersion` фолдит все пары разом → пер-парный хеш (родня 115/120); (в) дешёвая перекупка: `tmctl resnapshot --dry-run` — байт-сверка тел по чекпойнтам (`msgsContentHash`), идентичные юниты пере-привязываются без пере-вызова, платятся только изменившиеся. «Поведенческий отпечаток вместо строки версии» отложен (пол ≠ доказательство) | бэкенд | когда-нибудь (перед МАСШТАБОМ — когда перекупки станут реальными деньгами) | дизайн-пак по D39.97 п.5 | D39.97 | +| 221 | **Джойн «предложено × решено × нерешено» живёт ТОЛЬКО в движке.** Читаемый банк несёт итоги без предложений, карта подписи — предложения без решений; семантика «решено ли» (`ownerHandled`) существует в двух файлах движка и больше нигде (греп по трём зонам). Экран подписи при разморозке фронта заставит платформу пере-реализовать движковый закон у себя — дубль, запрещённый п.6 закона шва. **Фикс:** движок публикует нерешённость (секцией банк-экспорта или отдельной проекцией) — но ТОЛЬКО когда экран закажут: рефакторить под несуществующий экран не надо. Сейчас — ноль кода ⚠ **КОНСИЛИУМ 27.08 (оркестратор №19 + автор движковой двери), итог записан, чтобы его не выводили заново.** **(1) Это ОДИН дефект, а не три:** 221 и 224 — ось СОДЕРЖАНИЯ (проекция не несёт предложенное и не несёт джойн), остаток компаньона — ось СВЕЖЕСТИ (дверь пишет источники мгновенно, проекция ждёт границы прогона, которой при стоящем прогоне не наступает). Классический разрыв CQRS. Чинить порознь = три полу-лечения. **(2) Поле `BankTerm.decision` МЕРТВО СТРУКТУРНО** — довод сильнее прежнего «запрет владельца»: decline выражает себя ИСЧЕЗНОВЕНИЕМ строки, а не значением поля (`writeAutoBank` делает `continue` на `ownerHandled`, `mining.go:709+`), и негде показаться ни в одном из трёх окон; для approve поле избыточно — `status: approved` публикуется. Проверено двумя независимыми трассами. ⚠ Вопрос был СНЯТ ещё D39.144 вместе с ложной посылкой «марш к нулю, 17 из 300»; сегодняшняя потребность иная и уже — перезагруженный экран показывает СДЕЛАННЫЕ ПРАВКИ. **(3) Форма-кандидат Д′:** ДВЕ проекции, у каждой РОВНО ОДИН писатель — «решено на границе» пишет прогон рядом с картой, «решено после границы» пишет дверь при записи; экран склеивает по паре (поверхность, `map_id`), счёт приезжает ПОСЧИТАННЫМ. Правило единственного писателя остаётся буквально, поправка онтологии НЕ нужна. Конверт карты из дофикса-2 получает здесь первого потребителя. ⚠ Колонка `undecided` обязана ехать с тем же НЕ-гейтовым контрактом, что `SignatureState`, иначе пер-термная модель вернётся через новую проекцию. **(4) Подпункт «история»:** `glossary_revisions` построен наполовину — читатель вызывается только из тестов, графа `reason` заполняется литералом `seed-replace`, а ревизия пишется лишь для ОСТАВШИХСЯ строк, то есть журнал слеп к отклонениям; владельческий `note` доезжает до вида (`glossary.go:41,161`) и не публикуется ни одной проекцией. ⚠ Journal append-only: не заказать ревизии без исчезновений задним числом уже не выйдет. **Пак не заказан — ждёт слова владельца** | бэкенд | гейчена разморозкой фронта | аддитивное поле проекции | приёмка двери 27.08, D39.158 | +| 222 | **ВНУТРИкнижный остаток оси арбитра: второй конфиг ТОЙ ЖЕ книги с другим `project_db` пишет ту же пару файлов решений под ДРУГИМ локом**, мимо флока живого прогона. Достижимо по построению: пути решений считаются от каталога `book.yaml` и `book_id`, лок — от `project_db`. Рукотворная конфигурация оператора (две базы одной книге), лечение трогает ратифицированный п.2 закона (второй арбитр на идентичности файлов решений либо отказ при загрузке). ⚠ Межкнижная версия ЗАКРЫТА снятием объявляемых ключей (D39.158 п.5) | бэкенд | когда-нибудь (непропорционально: правка ратифицированного закона ради операторского футгана) | второй арбитр ЛИБО отказ при загрузке | приёмка двери 27.08, D39.158 | +| 223 | **Майнерский хвост за потолком структурно недостижим.** Потолок эмиссии (200) применяется ДО фильтров пригодности, сида и отказов, а детектор кандидатов сида и отказов не видит вовсе — репозиторий пишет это про себя дословно. Замер: 2110 ранжированных → 442 годных во всём алфавите → 117 внутри окна потолка → **325 невидимы постоянно**; отклонение всех 117 не подняло ни одного. ⚠ Решения владельца слотов НЕ освобождают, и это верно СЕГОДНЯ, а не следствие флажка; цитата «пере-предлагается once these are signed or declined» относится только к ОБРАТНОЙ секции. Двигать потолок — трогать фрозен-паритет, отдельное решение. Якорь-пин: `internal/miner/emissioncap_test.go` | бэкенд | когда-нибудь | решение о потолке, не правка | приёмка двери 27.08, D39.158 | +| 224 | **Банк-экспорт на стопе ПУСТ** — проекция, наиболее пустая ровно в момент, когда её читает экран подписи. Замерено: стоп с двумя предложенными термами даёт `total=0`, авто-банк на стопе отсутствует, потому что он пишется только в ветке авто-продолжения; при этом комментарий рядом называет стоп «границей, которую читает экран подписи», а платформа читает именно `.bank.json`. Член класса «проекция без контракта потребителя» (`architecture/18-bank-ontology.md`) ⚠ **ФОРМУЛИРОВКА ПРОТУХЛА, испр. оркестратором 05.09 по итогу стратегического веера:** лид говорит «экспорта на стопе нет, пишется только в ветке авто-продолжения» — сегодня `exportBank(ctx, "bank-mining/signature-stop")` НА СТОПЕ ЕСТЬ (`backend/internal/pipeline/mining.go`, греп `signature-stop`). Отсутствует не ВЫЗОВ, а НАПОЛНЕНИЕ: `exportBank` проецирует таблицу глоссария, а майненные строки попадают в неё только через `writeAutoBank`+`seedGlossary`, и оба лежат ВНУТРИ ветки `if !stopping`. ⇒ Экран подписи читает артефакт, гарантированно пустой ровно от тех строк, ради которых открыт. **Кто пойдёт чинить по прежнему тексту — будет искать несуществующий пропущенный вызов.** | бэкенд + платформа | скоро (держит экран подписи вместе с 221) | публиковать предложенное на стопе | приёмка двери 27.08, D39.158 | +| 225 | **Гейт «строка `open`, а лекарство уже в дереве».** При лендинге пересекать ПОЛНЫЕ пути застейдженных файлов с якорями открытых строк регистра и бэклога; совпадение — вопрос лендеру, а не находка следующего пака. Замерено прежде решения: по именам файлов 22 совпадения, почти все ложные; по полным путям 2, оба настоящие, и один из них (`PD-157`) убил мой же лендинг `d1eb8a9`. Норма-половина уже стоит в `platform/docs/ENGINEERING_STANDARDS.md` §3 п.8; здесь — машинная половина, режимом `counts.py` | оркестратор | скоро (окупился до постройки) | режим `counts.py`, берущий список путей и печатающий открытые строки, чьи якоря в них целят | приёмка пака P8-REVIEW 27.08, D39.159 п.7 | +| 226 | **История ПРЕДЪЯВЛЕННОГО не ведётся — «почему меня не остановило на этом термине» ответить нечем.** Карта и человеческая таблица стопа перезаписываются каждым прогоном, память флажка — плоское множество поверхностей без `map_id` и без времени. Это прямая расплата за то, что стоп срабатывает ОДИН раз (кластерная память, названный остаток дофикса-2), и единственная возможная диагностика спора. Кандидат в пак решённости, не заказ. ⚠ Шестое, названное консилиумом и оставленное владельцу: авторство и время решения — сегодня цена нуля (владелец один), станет нужным при мультипользовательской платформе, и тогда его захотят ЗАДНИМ ЧИСЛОМ | бэкенд | скоро (диагностики нет вовсе) | движок метит предъявленное `map_id` и временем; оверлей отвечает «что предъявлялось на прошлом стопе» | консилиум по читающей стороне банка 27.08 | +| 250 | **Заголовок глоссария на проводе ОПИСЫВАЕТ маркер, которого после пака больше нет — живая строка с висячей ссылкой.** Строка данных `ru glossary_header` (`backend/internal/lang/data/injection.txt`) дословно объясняет модели: «строки с пометкой ⟨проверить⟩ — неподтверждённые кандидаты», а пункт 3 вайр-батча снимает маркер с провода по `D39.104` п.2 ⇒ на проводе не останется НИ ОДНОЙ помеченной строки, а заголовок продолжит объяснять пометку. ⚠ Это НЕ мёртвая строка данных (те — `editor_unverified_header` и `unverified_marker`, они просто перестают читаться), это ЖИВАЯ строка, которую читает модель. По `D39.104` п.1 клаузула становится ВАКУУМНОЙ, а не ложной, вред не измерен — поэтому не блокер. ⛔ **Чинится ТОЛЬКО правкой `injection.txt`, а она двигает `EmbeddedVersion` → `cutTag` → ключ манифеста → снос `unit_resolutions` книги (строка 198).** Носитель — ближайшее ОКНО правки эмбед-данных: строка **160** идёт своим паком и всё равно бампает форму манифеста. Найдено бэкенд-сессией вайр-батча 04.09 — она правильно НЕ тронула и принесла предмет | бэкенд | скоро (в окне строки 160) | правка `injection.txt` в окне 160 | пинг бэкенд-сессии 04.09 | +| 251 | **Банковый контур в `pipeline-c1.yaml` требует АРТЕФАКТА, которого в git нет и быть не должно — первая же выкатка после лендинга откажется стартовать, если его не положили.** Оба банк-роля живут ВНУТРИ стопа майнинга, а `runBankMiningStop` (`backend/internal/pipeline/mining.go:58`) возвращается РАНЬШЕ построения кандидатов при пустом `mining.contrast_path` ⇒ без корпуса контраста терминолог и классификатор не исполняются ВООБЩЕ, чем бы ни были заполнены их гейты. Артефакт — общечастотный словарь jieba (`.gitignore:38`: «jieba 0.42.1 dict.txt, 5MB — SHA pinned in the report, **reproducible**»), рецепт и sha256 `7197c321…` — `docs/experiments/16-bank-mining.md` (греп `jieba_dict_general_zh`). ⚠ **Риск ограничен и это ГЛАВНОЕ:** артефакт не утерян, а ВОСПРОИЗВОДИМ по запиненному рецепту; дыра в том, что требование не доехало до РАНТБУКА развёртывания (`platform/deploy/README.md` о нём не знает), и оператор узнаёт о нём только от гарда. Гарды поставлены паком и они правильные: загрузка ОТКАЗЫВАЕТ при включённом гейте с пустым ключом, наличие файла проверяется на ПИШУЩЕМ пути рядом с `CheckKeys` — то есть до оплаченной черновой волны, а не после неё. ⛔ **Что делать:** требование в рантбук платформы (её зона, пинг) + слово владельца/оператора, что файл лежит на боевой машине, ДО первой выкатки после лендинга. ⚠ **Вторая половина, вскрытая тем же включением:** корпус контраста — факт ИСХОДНОГО ЯЗЫКА, а `mining.contrast_path` живёт в конфиге пайплайна, который по построению пар-агностичен (цель проекта №2). Перекос не заведён паком, а вскрыт им; пара, которой в репо нет, потребует своего корпуса и своего ключа | бэкенд+платформа | скоро (до первой выкатки после лендинга вайр-батча) | пинг рантбуку + слово оператора; пар-перекос — отдельным решением | бэкенд-сессия вайр-батча 04.09 | +| 252 | **Две гарантии не прибиты — мутации сессии ПЕРЕЖИЛИ всю батарею** (собственные посадки бэкенд-сессии вне шести пунктов заказа, 04.09; из восьми посадок шесть красные, две выжили и НЕ чинились как вне-заказные). **(а) `StickyDepth = 2 → 1` не ловит НИКТО** — глубина окна липкости меняется молча. **(б) `priorityRank`, отбрасывающий приоритет доверия** (подтверждённые строки раньше неоднозначных в бюджете инъекции), **не ловит НИКТО** — то есть порядок, решающий, ЧТО попадёт в инъекцию при нехватке бюджета, можно перевернуть безнаказанно. ⚠ Класс тот же, что дал паку «число согласия» три неприбитых свойства: заявленное поведение без пинящего теста. Сессия правильно НЕ чинила вне заказа и принесла предмет | бэкенд | скоро (ближайшим касанием инъекции) | по тесту на гарантию + запись в `cmd/tmmutate/mutations.json` | собственные посадки бэкенд-сессии 04.09 | +| 253 | **НА ЭКРАНЕ ПОДПИСИ БАНКА ПОДПИСЫВАТЬ НЕЧЕГО, а сам подписываемый банк НЕПОЛОН — две половины одного шва, найдены ПЕРВЫМ живым прогоном 04.09.** **(а)** ⚠ **ЭТО ТОТ ЖЕ ДЕФЕКТ, ЧТО СТРОКА 224 — испр. 05.09:** корень там уже найден и назван (майненные строки пишутся внутри ветки `if !stopping`), поэтому «разобрать порядок публикации» здесь заказывать НЕЛЬЗЯ — работа удвоится. Половина (а) закрывается лендингом 224; живой в этой строке остаётся только (б). Прогон встал `awaiting_bank`, `GET /bank` отдал `total 0, signed 0` — при том что рядом лежали `mined-signature.yaml` 49 КБ и `bank-stop.txt` 60 КБ, а движок держал 82 неразобранные поверхности; термины появились в read-модели только на СЛЕДУЮЩЕМ прогоне (`bank export refreshed … terms=83`). Платформа читает сайдкар честно: 0 значит 0 ⇒ либо сайдкар пишется не в тот момент, либо стоп наступает РАНЬШЕ публикации банка. Корень скорее движковый. **(б)** Банк, который пользователь подписывает, ЧАСТИЧНО КОНСОЛИДИРОВАН, и платформа об этом не знает вовсе: терминология урезала план под бюджет ДО первого вызова (`batches_dropped=5`, `consolidated=38 declined=0 unanswered=47` из 85), а поверхности нет ни одной — `grep -rn 'consolidat\|unanswered\|batches_dropped' platform/internal/ --include=*.go` → **0**, аллоулист сайдкара несёт только термины. ⇒ **пользователь подписывает как ПОЛНЫЙ банк то, что движок сам называет неполным.** Лечение (б) — КАНАЛ: полнота консолидации в сайдкар + поле на `BankPage`; лечение (а) — разбор порядка «стоп против публикации». ⚠ Обе половины на шве, чинятся согласованно | бэкенд+платформа | скоро (до первого внешнего пользователя) | разбор порядка публикации + канал полноты | наблюдение платформы за живым потоком 04.09, H10/H11 | +| 254 | **Шесть движковых ловушек, увиденных ПЕРВЫМ живым прогоном (04.09) и НЕ тронутых платформой — чужая зона.** ⚠ **ОДНА ИЗ ШЕСТИ РЕШЕНА ВЛАДЕЛЬЦЕМ 05.09 — остальные ПЯТЬ живы, строку не закрывать** (испр. 05.09; строка 285 закрывает ровно эту одну и не больше). ⛔ Решённая — самая дорогая: `manifest` на пустом файле даёт exit 11, а интейк на 11 УДАЛЯЕТ ЗАГРУЗКУ ⇒ пользователь, приславший пустой файл, терял его. **Лечение названо владельцем: fail fast на загрузке** — строка **285**. · `tmctl build` не читает контекст: всегда SIGKILL, staging-файл `.tmp-*` остаётся · потолок бросает летящие вызовы, они списываются нулём (`PD-441`, замер: отмены на 120756/156469/156470 мс) · терминология МОЛЧА режет план под бюджет (вход строки 253б) · сайдкар банка пуст в момент стопа (вход 253а) · **`build --format X` без `--out` удаляет соседние форматы** — ловушка для оператора с руками. ⚠ Ни один из шести не найден чтением кода за месяцы — все шесть увидены за один прогон | бэкенд | скоро (ближайшим касанием соответствующего пути) | по пунктам; часть — райдерами других паков | наблюдение платформы за живым потоком 04.09, H21 | +| 255 | **Первый живой прогон НЕ КОСНУЛСЯ поверхностей, ради которых часть кода построена — и это надо знать прежде, чем говорить «поток проверен».** **SSE-поток не открывался НИ РАЗУ** (весь прогресс читался поллингом ⇒ `platform/internal/httpapi/stream.go` живым прогоном не проверен вовсе) · читающая поверхность глав и пар не читалась · пользовательский `stop` не звался — из ТРЁХ способов кончить прогон проверены два · апгрейд движка, `books --migratable`, `run unquarantine` не трогались · всё измерено на книге **57 КБ**, на корпусной 23 МБ переносить нельзя. ⚠ Это не дефект, а ГРАНИЦА утверждения: «цикл замкнут живьём» верно ровно про ту цепь, которую прошли. Следующий платный прогон обязан закрывать этот список, а не повторять пройденное | платформа | скоро (следующий платный прогон) | список к покрытию | наблюдение платформы за живым потоком 04.09, H22 | +| 256 | **Лейбловая ветка `CheckKeys` прибита только СПИСКОМ — БЛИЗНЕЦ денежной дыры, закрытой на безлейбловой.** Безлейбловую ветку круг 3 починил определением `gateModels()` и прибил вызовом самого `CheckKeys`; лейбловая по-прежнему держится тестом на СПИСОК (`TestABankModelIsAReachableModel`) — тем самым способом, про который тот же круг записал «пин на списке не есть пин на префлайте». Посадка круга 4: лейбловая ветка собирает модели стадий вместо `ReachableModels()` — ВЕСЬ пакет зелёный. Проба предъявлена: лейблованная книга с банк-моделью на провайдере без ключа проходит префлайт целиком. Симптом денежный и тот же: покупается черновая волна, смерть на воротах. ⚠ Не чинилось только потому, что круг свёрнут решением владельца | бэкенд | скоро | пин на вызове `CheckKeys` для обеих веток + проба под лейблом | круг 4 петли, X40 | +| 257 | **Порядок `bound()` перед `reconcile` не держится ничем, и цена — исчезнувшее сообщение оператору.** Перенос блока `bound()` после `reconcile` пережил весь пакет. Проба: книга в одну главу, второй прогон под грантом 1, редактор отказывает — единственная работа вне гранта флагуется; оригинал печатает «1 PAID FOR BUT FLAGGED», под посадкой **отчёт об объёме = nil**, то есть раскрытие, ради которого он построен, пропадает целиком. ⚠ Комментарий коммита посылает читателя в юнит-тест `volumeScope`, который порядок в `waverun` увидеть не может — второй экземпляр класса «тест утверждает не то, что думает» | бэкенд | скоро | пин порядка в `waverun`, а не в `volumeScope` | круг 4 петли, X14 | +| 258 | **Конструктор `classifyInputFor` можно захардкодить на `ru`/`zh` — вся батарея зелёная, и причина СТРУКТУРНАЯ: через раннер нет ни одной фикстуры с не-ru целью.** Есть только zh→ru и ja→ru. Рефлексивный пин круга 3 ловит «поле нулевое», но не «поле взято не у книги». Пробы предъявлены: →ja книга с китайским выводом под посадкой перестаёт быть →ja. ⚠ Бьёт прямо в цель №2 (ревью-вопрос «заработает ли пара, которой в репо нет, без правки Go»): сегодня ответ на него не может дать ни один тест. Родня — 259 | бэкенд | скоро | фикстура не-ru цели ЧЕРЕЗ раннер + пин «поле взято у книги» | круг 4 петли, X1/X2/X3 | +| 259 | **Настоящей латинописьменной цели в репозитории НЕТ — `target-en.txt` не существует, и →en достижим только через пустое объявление.** Следствие: часть общности проверяется рассуждением, а не тестом, и пара, которой в репо нет, не может быть предъявлена живьём ни одним прогоном. Замер общности 04.09: ветвлений Go по конкретному языку два на обе зоны, оба — проверка на пустоту; книжной специфики в Go нет, кроме константы худшей строки банка (строка 40) | бэкенд | скоро (гейт второй пары) | минимальный langpack →en + прогон на нём | замер общности оркестратора 04.09 по требованию владельца | +| 260 | **Экран цели калиброван на ОДНОМ сянься и даёт ложный `off_target` на латинице-тяжёлом здоровом русском** (0.461 с пиньинем при пороге). ⚠ Ложный флаг ЭСКАЛИРУЕТ, то есть стоит ПЛАТНОГО хопа за здоровый текст — это деньги, а не только шум. Порог и пол улики обязаны быть пере-калиброваны на корпусе, включающем латиницу-тяжёлый русский | бэкенд | скоро | пере-калибровка на расширенном корпусе + пин границы | самоотчёт бэкенд-сессии о непокрытом, круг 3 | +| 261 | ⛔ **ОСТАТОК СНЯТОЙ СТРОКИ 277 ЖИВЁТ ЗДЕСЬ (возвращён 05.09 по ревью — при закрытии 277 он едва не потерялся): остаток `PD-441` = **261 + 262** (третья часть, строка 277, ПОСТРОЕНА и закрыта D39.206 — «одним паком» уже невозможно).** Пак «денежный стоп» (акт D39.206) снял только ОТМЕНУ допущенного; **структурный корень невидимого расхода — эта строка**, а сверх-утверждение комментария ветки отмены — строка **262**. ⇒ платформенной зоне: `PD-441` закрывать «паком денежного стопа» НЕЛЬЗЯ, он закрыт наполовину. **`BilledDecodeError` виден только когда ретрай НЕ спас: успешный ретрай стирает оплаченную попытку из леджера.** Тип заведён, чтобы оплаченный-но-нечитаемый вызов стал ВИДЕН (рантайм доседает по оценке), но `retryLoop` при успехе возвращает ответ и предыдущую ошибку выбрасывает — рантайм видит один успешный ответ и седит его `Usage`. Оплаченный 2xx перед ним не попадает никуда. ⚠ Бьёт не в отчётность, а в ЦЕЛОСТНОСТЬ потолка: допуск выдан под ОДНУ оценку, а под ней могло пройти до трёх запросов (`MaxAttempts` 3), и `Reserve` об этом не узнает. Комментарий рядом сам говорит «each retry is a new billed 2xx» — авторы знали и закрыли только детерминированный случай (усечение). ⚠ ЧАСТОТА пути НЕ измерена | бэкенд | скоро (вместе с денежным паком) | единица учёта = единица биллинга + вендор-факт по правилу квирков | чтение под вопрос, бэкенд-сессия 04.09 | +| 262 | **Комментарий ветки отмены — сверх-утверждение: «No 2xx ever arrived: nothing was billed» описывает ветку ШИРЕ, чем она есть.** Верно для отказа соединения, DNS, таймаута до первого байта и терминального 4xx; ложно для вызова, который отменили МЫ после начала генерации — он приходит в ту же ветку через `context.Canceled`. Правка отложена намеренно: ветка денежная, лечение структурное (см. 261), однострочная правка фразы разъедется с решением | бэкенд | скоро (вместе с 261) | привести ветку и её описание к одному радиусу | чтение под вопрос, бэкенд-сессия 04.09 | +| 263 | **Дизъюнкты предупреждения банкноты и `forWrite` не прибиты по отдельности** (позитивная фикстура без обоих входов, негативная — с обоими): пережили посадки «нет контраста», «нет пака», «предупреждать и на read-open». **`WB15` несёт тот же дефект ложного пина, что найденный и починенный `WB36`** — одиночный сдвиг порога под `TestGoldenDeterminism`: на чистом литерале голден не двинется и запись выживет при целой гарантии. **AST-тест исчерпаемости парсит ТОЛЬКО `disposition.go`** — `FlagReason`, объявленный в другом файле, в карту не попадёт при зелёном тесте. **Дайджест корпуса не покрывает `provenance`** — адрес пере-снятия, подмену которого дайджест не видит | бэкенд | когда-нибудь | четыре независимых пина | круг 4 петли, X11/X12/X13 · WB15 · X9 · X30 | +| 265 | **Питоново зеркало полигона держит ВТОРУЮ копию таблицы плейсхолдеров движка, и она разошлась: `genre` есть, `book_id` нет.** `eval/bank_arbitration/editor_wire_probe.py` — ПЛАТНАЯ проба, читающая ШИППИНГОВЫЙ `backend/prompts/zh-ru/editor.md`, на неё ссылаются ещё **25** скриптов (`grep -rl editor_wire_probe eval --include=*.py`; ⚠ испр. 05.09, первая редакция говорила «девять»); 27 промтов под `eval/` несут `{{genre}}`, который движок ОТКАЗЫВАЕТСЯ собрать при загрузке. ⇒ замеры идут на проводе, которого в проде не существует, и это «третий путь», которого в Go больше нет. ⚠ Зона ПОЛИГОНА — чинит она, носитель заведён оркестратором пингом | полигон | скоро (перед следующим платным замером) | зеркало читает таблицу движка, а не держит копию | передано бэкенд-сессией 04.09, чужая зона | +| 266 | **Правки кругов 3 и 4 петли не ревьюил НИКТО — круг свёрнут решением владельца, а не замкнут.** Замеренная база, из-за которой это долг, а не формальность: ДВАЖДЫ подряд дефект вносил фикс предыдущего круга (круг 2 объявил денежную дыру закрытой — круг 3 показал, что она открыта; ратификация оркестратора по дедупу внесла живой дефект — поймала зона). Круг 3 добавил ~2000 строк и не ревьюил из них ни одной; круг 4 — две правки, обе проверены исполнением, но не чужими глазами. ⚠ Дисциплина петли исправлена эрратой: круг крутит СЛЕДУЮЩАЯ сессия по готовому паку, а не прежняя — правило «сессия отрабатывает скоуп и завершается» бьёт норму петли | бэкенд | скоро | проход свежей сессии по диффу `c77c3ba`+`2e13cd1` | решение владельца 04.09 остановить полировку | +| 267 | ⛔ **ОДИН ТЕРМИН В ОДНОМ СМЫСЛЕ МОЖЕТ НЕСТИ ДВЕ КОНКУРИРУЮЩИЕ ФОРМЫ, И ОБЕ ЕДУТ НА ОБА ПРОВОДА — дыра в ПРОВЕРКЕ схлопывания.** ⚠ **Пере-снято 05.09: было заведено как ДОКТРИНА («показывать обе или схлопывать») — это была неверная постановка оркестратора.** Владелец: у неподписанного термина тоже обязан быть ОДИН перевод, отвечает за это стадия схлопывания, подпись ни при чём. **Измерено зоной по коду и предъявлено на банке:** ключ уникальности БД — `(book_id, src, sense, since_ch, until_ch)`, значит один смысл при РАЗНЫХ окнах законен для БД; гард «одна форма на главу» существует (`backend/internal/pipeline/memseed.go`, греп `a term has ONE rendering per chapter`) и статус-слеп, **но работает ВНУТРИ ОДНОГО ФАЙЛА** — `loadMinedDelta` проверяет дельту саму против себя и НЕ против сида; точка слияния (`bankmaterialize.go`, греп `storeOrder`) отвергает только ТОЧНЫЙ дубль, перекрывающиеся окна проходят. Предъявлено: сид `[0,0]` «юаньши» + майнинг `[3,9]` «камень первоисточника», глава 5 внутри обоих ⇒ **injected=2, две строки и редактору, и черновику**. ⇒ Банк перестаёт быть законом ровно там, ради чего построен — консистентность термина на всю книгу. ⚠ **ГРАНИЦА, названная зоной: доказано, что состояние ДОСТИЖИМО и провода его несут; НЕ доказано, что обычная последовательность операций его производит** (консолидация даёт один `dst` на термин — сверено; сверяет ли она предложение с УЖЕ существующей сид-строкой другого окна — не мерено). Это дыра в проверке, а не наблюдённый инцидент. Чинить на СЛИЯНИИ, где видны все три источника, а не на загрузке каждого | бэкенд | скоро | гард перекрытия окон на слиянии + пин на достижимом состоянии | решение владельца 05.09 + замер зоны | +| 268 | **Гейт версии контракта у фронта читает СВОЁ зеркало, а не канон — и потому слеп по построению.** `frontend/src/api/contract.test.ts` сверяет `${cwd}/docs/api-contract/openapi.yaml` с фикстурой, то есть копию с копией, и зелен при любом отставании; соседний тест сравнивает только МАЖОР, а он у `0.2.3` и `0.10.0` одинаков — ноль. Зеркало отстало на ВОСЕМЬ миноров. Сравнение: тот же класс гейта у платформы читает КАНОН с диска и поймал расхождение `0.9.0→0.10.0` в тот же час. ⚠ Зона фронта ЗАМОРОЖЕНА — строка ждёт разморозки, но входит в перечень первого касания | фронт | скоро (первое касание при разморозке) | перенацелить гейт на канон | находка платформенной сессии 04.09, подтверждена оркестратором | +| 272 | **ШАБЛОН КНИГИ ДЕПЛОЯ ОДИН НА ВСЕ ПАРЫ, а в нём лежит ПАР-СВЯЗАННОЕ значение — `transcription: palladius`.** Платформа рендерит `book.yaml` из единственного операторского шаблона и подставляет ровно пять ключей (`book_id · title · source_lang · target_lang · source_file`); всё остальное едет из шаблона нетронутым. Палладий — система транскрипции ДЛЯ КИТАЙСКОГО. Движок значение не валидирует (свободная строка) и подставляет прямо в промпт. ⇒ Деплой, объявивший `zh>ru,ja>ru`, отдаёт КАЖДОЙ японской книге инструкцию транскрибировать по-китайски: не отказ и не флаг, а тихо неверные имена во всей книге — ровно тот класс брака, ради которого продукт существует. ⚠ Чинить придётся не одну книгу: значение вшито в `book.yaml`, который платформа НИКОГДА не перезаписывает (`O_EXCL`) | платформа+бэкенд | скоро (гейт второй пары) | пар-связанные ключи шаблона + валидатор значения в движке | критик полноты стратегии 04.09 | +| 273 | **ПАР-ШОВ ЛОМАЕТСЯ АСИММЕТРИЧНО: промпт-пак падает ГРОМКО, целевые ДАННЫЕ выключаются МОЛЧА — вместе с банком.** Отсутствие промптов пары — жёсткая ошибка загрузки («never silently substitute another pair's conventions»). Отсутствие ЦЕЛЕВЫХ данных — тишина в трёх местах: `lang.InjectionTextsFor` на незнакомом таргете возвращает пустое, обе банк-инъекции рендерят пустоту (`if !tx.HasData() { return "" }`), `LoadReaderWords` отдаёт значки вместо слов без ошибки. ⇒ Книга на новый таргет переводится ЦЕЛИКОМ и за ПОЛНЫЕ деньги, но БЕЗ банка-как-закона — то есть без единственного механизма, держащего термины консистентными на всю книгу, без $0-чекеров цели и с пометками из значков в выданном файле. Ни ошибки, ни варнинга, ни поля в отчёте сборки. ⚠ Строка 32 закрыта формулировкой «инертна ПО ОТСУТСТВИЮ данных» — для ЧЕКЕРОВ это хорошо, для БАНК-инъекции такого вывода не делал никто | бэкенд | скоро (гейт второй пары) | префлайт готовности таргета: банк-данные есть ⇒ работаем, нет ⇒ громко | критик полноты стратегии 04.09 | +| 275 | ⚠ **ПЕРЕ-СНЯТА 05.09 СЛОВОМ ВЛАДЕЛЬЦА — прежняя формулировка «КАЧЕСТВО НЕ МОЖЕТ СТАРТОВАТЬ ВООБЩЕ» БЫЛА НЕВЕРНА (ошибка оркестратора).** Она называла четыре гейта; из них **три сняты словом владельца, четвёртый гейтом не был** (разбор — `D39.198`): **13а** веса рубрики НЕ НУЖНЫ — веса меряют РАЗНЫЕ узлы (консистентность — банк памяти, выдумки — редактор, художественность — редактор И черновик), единого веса быть не может, а одно взвешенное число измеряет, но не ДИАГНОСТИРУЕТ · **24** профили голоса — приоритет №3, подписи владельца не требуют («зачем мне это подписывать») · **149** разморозка панели не нужна: пока идут доработки, менять жильцов ролей незачем · **55** прогоняем на ТЕХ ЖЕ текстах (мастер Гу, Жан-Кристоф), оговорка про претрейн остаётся ОГРАНИЧЕНИЕМ ВЫВОДА, а не требованием новой книги. **ЧТО ОСТАЁТСЯ ЖИВЫМ В ЭТОЙ СТРОКЕ:** привязать каждый класс дефекта к УЗЛУ и мерить по узлам; поставить порог остановки для приоритетов №1 и №2 (разъехавшийся термин — стоп, выдумка — стоп, сухая фраза — не стоп). ⚠ Консистентность проверяема ДЕТЕРМИНИРОВАННО за $0 — это ГЕЙТ, а не строка рубрики; ближайший её носитель — строка **267** | полигон+бэкенд | скоро | привязка классов к узлам + пороги остановки для №1 и №2 | решение владельца 05.09, `D39.198` | +| 276 | ⭐ **ФОРМА ЗАКАЗА ПЕРЕВОДА — решение владельца 05.09, ратифицировано D39.196.** На аккаунте **баланс в ДЕНЬГАХ** и он виден. Человек стартует перевод; хочет задать потолок — тянет ползунок **в деньгах**; рядом ответ на его настоящий вопрос: **хватает на полную книгу или нет**. Хочет задать объёмом — второй ползунок: **ГЛАВЫ когда книга распозналась**, **ЗНАКИ когда нет** (о нераспознавании говорим ЯВНО). Старт = **холд с баланса**. Отдельная кнопка **«перевести книгу целиком»** — за целую книгу оценка точнее, чем за произвольный кусок. ⚠ **Две ручки связаны проекцией:** объём — ЗАКАЗ (главная), деньги — ЛИМИТ (вторая); тронутая последней ограничивает, другая пересчитывается и показывается производной («5 глав ≈ $0.55, зарезервируем до $0.8»); минимум денежного ползунка = неделимый шаг движка, чтобы ползунком нельзя было выразить невозможный заказ. Не тронута ни одна ⇒ заказ = вся книга. ⚠ **Цифра на экране — ПАРА, а не точка:** «ожидаемо ≈ $1.1, зарезервируем до $1.6, спишем по факту», и закрытие фактом после прогона — проекция имеет дисперсию (редакторские вызовы 25–90 % worst-case), точечное число превратится в «сказали 1.14, списали 1.31». Главный ответ — фраза, цифра рядом и мельче. ⚠ **Запрет «денег в UI» ОТОЗВАН владельцем** (D39.196 п.2): виден баланс, потолок, холд; цены моделей и стадий — нет. «Страница» из контракта убирается совсем — владелец назвал ЗНАКИ, форматирование «≈67 стр.» это локаль фронта. Исполнение — **279–283** (⚠ испр.: 277 и 278 ПОСТРОЕНЫ лендингом `81a89e9` и сняты) | движок+платформа+фронт | скоро | решение принято и ратифицировано D39.196; исполняется **279–283** (277 и 278 закрыты) | решение владельца 05.09 + сведение с внешним рецензентом | +| 279 | ⚠ **ПРОТУХЛА — испр. 06.09: половина ИСПОЛНЕНА без пометки, половина осталась остатком без имени.** Форма `OrderOptions` (`chapters_left`, `affordable_chapters`, `verdict`) стоит в каноне с минора 0.11.0, а `shortfall` в каноне ОТСУТСТВУЕТ (ноль вхождений); тело `D39.208` строку не называет, ✅ не стоит. Класс `D39.167` п.1: акт лендинга обязан быть сверен со строками. ⇒ разделить: исполненное пометить, остаток `shortfall` назвать своим предметом. **ШАГ 3, КОНТРАКТ (минор, полоса ломающих правок мажора 0 законна): заказ объёмом.** `ceiling_chapters` → `chapters` со смыслом ОБЪЁМА (`null` = вся книга) · `CeilingBounds{min,max,default}` → `OrderOptions{chapters_left, affordable_chapters, verdict: covers_all|covers_part|covers_none, blocked}` · `PausedReason` += `run_limit_reached` (и `credit_exhausted` СТАНОВИТСЯ правдой — сегодня лжёт при 34% баланса, наблюдение H14) · `Run` += `ordered_chapters`/`delivered_chapters`. ⚠ Фразы — ДАННЫМИ по коду причины и локали, не литералом. ⚠ **ПЕРЕ-СНЯТО 05.09 под D39.196:** наружу ВЫХОДЯТ баланс, потолок заказа и холд — деньгами; контракт получает `balance`, `estimate{expected, hold}` под выбранный заказ, границы денежного ползунка `{min: неделимый шаг, max: баланс}` и `shortfall` у паузы; процент остатка остаётся СИГНАЛОМ «мало/пусто». НЕ выходят: цены моделей, стоимость стадий и вызовов, структура НАШИХ расходов. Плюс `OrderOptions` обязан нести ТРИ вида заказа (вся книга · знаки · до главы N), а не только главы. Ремедиа-таблица `resumeRun` упрощается: «Продолжить» — новый прогон ТОГО ЖЕ заказа | контракт | скоро | минор контракта одним актом с платформенной половиной | согласование 04.09 | +| 280 | ✅ **ИСПОЛНЕНО ЛЕНДИНГОМ 06.09 — акт `D39.208`.** Заказ живёт на КНИГЕ и хранится ИДЕНТИЧНОСТЬЮ (`books.ordered_through_chapter_id`), а не ординалом; холд считается от проекции движка; `--max-units` едет в argv. ⚠ **Кроме ОДНОЙ позиции, от которой зона отказалась с доводом и которая живёт отдельно:** денежный ползунок объявлен на проводе, но отправить его нечем, и оценки под ВЫБРАННЫЙ заказ нет. Прежняя редакция ряда: **ШАГ 4, ПЛАТФОРМА: заказ живёт на КНИГЕ, холд считается от проекции, `--max-units` наконец едет в argv.** `books.ordered_through_chapter` (null = вся книга) — сегодня интент живёт на ПРОГОНЕ, оттого и неловкость «поднять лимит = НОВЫЙ прогон с бо́льшим `ceiling_chapters`»; с заказом на книге «Продолжить» после пополнения тривиален, и дверь пере-прохода встаёт рядом вторым типом заказа. Холд = `min(баланс, проекция × k)`; `bookCap = committed + холд` (`PD-158` цел). В argv добавляется `--max-units` = сумма юнитов заказанных глав минус доставленные. Удаляются `DefaultPerChapter`, `Scale` и `draftWork`: план движка становится РАВЕН заказу, и «черновики на весь потолок при нуле готовых глав» исчезает структурно. Закрывает `PD-410`, `PD-440`, `PD-446`. ⚠ **ПРЕДУСЛОВИЕ, названное отдельно: `PD-422`** — `--resnapshot` передаётся УСЛОВНО, а условие ставит только правка банка; рост авто-банка от майнинга флага не ставит. Частичный заказ на майнящей книге растит банк ⇒ следующий заказ без `--resnapshot` умрёт на снапшот-гарде, холд взят, попытка сожжена. Взять В ТОТ ЖЕ пак | платформа | скоро | заказ на книге + холд от проекции + проводка `--max-units` + PD-422 | согласование 04.09 | +| 281 | **ЗАМЕР: сколько наших денег стоит тысяча ПЛОТНЫХ и тысяча РАЗРЕЖЕННЫХ знаков по стадиям и парам.** Цель — НЕ константа (D39.165 п.1г прямо запрещает ставку константой), а **дисперсия проекции**: коэффициент k для холда и честность вердикта «хватит ли». Снимать есть из чего и это $0: `find -L books` даёт 162 базы прогонов, в `request_log` лежат `chapter · chunk_idx · stage · prompt/completion_tokens · cost_usd · tm_hit`, исходник по юниту отдаёт `tmctl export --pairs` бесплатно. Метод: по юниту плотные/разреженные знаки против суммы `cost_usd` при `tm_hit=0`, по стадиям; хвост ретраев и эскалаций считать ОТДЕЛЬНО; базы до 16.08 пере-прайсить по токенам. ⚠ Гейт для коэффициента холда в строке 280 | полигон | скоро (гейт строки 280) | замер по 162 базам, $0 | согласование 04.09, вторая редакция | +| 282 | ⛔ **ЧИСЛО, ПОДПИСАННОЕ «ЗНАКОВ», СЧИТАЕТ РУНЫ ПОТОКА ЗАПИСИ ФАЙЛА — что для UTF-8 txt И ЕСТЬ знаки, а для EPUB даёт руны ZIP-АРХИВА.** ⚠ Заголовок первой редакции («считает байты») — противоположная полуправда, испр. 05.09: ложно оно для EPUB, GB18030 и UTF-16, а не всегда. Проверено оркестратором по коду: `platform/internal/books/books.go`, греп `type counter` — счёт идёт по не-продолжающим байтам UTF-8 ПОТОКА ЗАПИСИ файла, а не по тексту; там же комментарий признаёт приближение для GB18030. Наружу уходит как `character_count` (`platform/internal/httpapi/v0.go`), на экране подписано `'about.characters': 'Знаков'` (`frontend/src/i18n/ru.ts`). ⇒ Живая ложь на продуктовом экране, и она же — вторая ненадёжная единица, найденная тем же вопросом «откуда берётся число». **Основой страницы быть не может.** Лечение: переименовать в размер файла ЛИБО заменить манифестной суммой знаков движка — ✅ **источник ПОСТРОЕН**: `source_chars` по юниту в `manifest --json` (лендинг `81a89e9`, акт D39.206; строка 278 закрыта и снята). Остаток строки — платформенная половина: взять число и снять ложную подпись. ⚠ Фронт заморожен — подпись правится при разморозке, число на платформе раньше | платформа+фронт | скоро | снять ложную подпись + заменить источник на манифест движка | согласование 04.09; проверено оркестратором по коду | +| 283 | **СТРУКТУРА ГЛАВ ДЛЯ ВЫДАЧИ — отдельная задача, которую «страница» НЕ отменяет, и она гейтит бету для не-CJK и EPUB.** Билдер кладёт по одному XHTML на главу движка и сам признаёт, что ридер делает главу из каждого документа spine (`backend/internal/bookfile/epub.go`) ⇒ **для не-CJK txt читатель получает книгу ОДНИМ ПОЛОТНОМ при любой единице заказа**. Состав — этап 1 `research/27`: EPUB по nav/NCX (обязательно по стандарту), FB2, индуктор оглавления для txt, разрез по ДАННЫМ ПАРЫ вместо захардкоженного CJK (сегодня асимметрия: распознавание строки-заголовка данные пары читает — `configs/langpacks/zh-ru/heading.txt`, — а РАЗРЕЗ на главы нет). ⚠ Делать в единственном окне пере-снапшота, пока платная книга одна: перекрой двигает нарезку. Пере-скоуп строк 160–162 | бэкенд | скоро (ДО открытия беты не-CJK и EPUB-входам) | этап 1 research/27 своим паком | согласование 04.09, вторая редакция | +| 284 | **НАЗВАНИЕ КНИГИ И ЗАГОЛОВКИ ГЛАВ ИДУТ ЧЕРЕЗ ТЕРМИНЫ — ОТДЕЛЬНОЙ СТАДИЕЙ (решение владельца 05.09).** ⚠ **СЮДА ЖЕ ПЕРЕЕХАЛ ОСТАТОК ЗАКРЫТОЙ СТРОКИ 274 (D39.201 п.7): доставка имени В ФАЙЛ.** Платформенная половина построена — имя вычисляется ПРИ СКАЧИВАНИИ (`platform/internal/httpapi/v0.go`, греп `exportName`), внутрь файла не пишется намеренно: движок сворачивает `title` в `BriefHash` → снапшот → каждый request-hash, то есть запись в `book.yaml` отказала бы следующему прогону недопереведённой книги и стоила бы ПЕРЕ-ОПЛАТЫ книги целиком. **ФОРМА ОПИСАНА, ПАТЧ НЕ ПРОВЕРЕН** (слово платформенной зоны, принято дословно): путь — `tmctl build --title` аргументом при спавне, прецедент `--ceiling-usd`, но НЕ предъявлено исполнением, что движок примет незнакомый флаг без правки разбора аргументов — по закону шва там громкий отказ по построению. Остаток регистра — `PD-450`. Сегодня их не переводит НИКТО: `dc:title` берётся из `book.yaml` как есть (`backend/internal/bookfile/epub.go`, греп `dc:title`), заголовок главы собирается детерминированно шаблоном из langpack (`backend/configs/langpacks/zh-ru/heading.txt`, `template Глава {n}`). ⇒ Русский EPUB приезжает в читалку с китайским названием — ломается первое, что видит человек. Владелец: «пусть едет как термины, причём отдельные, то есть как-то надо называть эту стадию». ⚠ Значит у стадии своё имя, свой бюджет и своя ПОДПИСЬ: название книги владелец утверждает так же, как утверждает термин. ⚠ Родня — строка 274 (ручка переименования у пользователя) и открытый лист владельца «что печатать на титуле и в имени файла» (D25.1): механизм строится, СЛОВО остаётся за владельцем | бэкенд | скоро | стадия перевода заголовков + подпись владельца | решение владельца 05.09 | +| 285 | **FAIL FAST ПРИ ЗАГРУЗКЕ вместо приёма-и-удаления (решение владельца 05.09).** Сегодня при загрузке проверяется ТОЛЬКО размер (`platform/internal/httpapi/middleware.go`, греп `LimitBody`); понять, есть ли в файле книга, умеет лишь движок и лишь при разборе — то есть ПОСЛЕ приёма и записи, а на классе «источник нечитаем» интейк УДАЛЯЕТ загрузку. Владелец: «почему просто не fail fast, как это обычно принято». ⚠ Механизм для этого есть и он $0: `tmctl manifest` режет книгу и возвращает число юнитов без ключей и без единого платного вызова, и платформа уже умеет его звать. Звать СИНХРОННО на загрузке: либо человек сразу видит «в этом файле книги нет» и файл не принят вовсе, либо получает принятую книгу и её объём. ⇒ **Снимает вопрос про удаление целиком — удалять нечего, если не приняли** (строка 254 закрывается этим). ⚠ Решить: латентность синхронного разбора на большой книге и что показывать, пока он идёт | платформа | скоро | синхронный $0-разбор на приёме + отказ вместо удаления | решение владельца 05.09 | +| 286 | ⚠ **ЧИТАТЬ ЧЕРЕЗ `D39.205`: стоп остаётся ЦЕЛЬЮ, но гейт `gates.glossary.postcheck_gate` владелец 05.09 ОТЛОЖИЛ до замера точности («Не знаю. Тут надо мерить типо?… ложные срабатывания — это плохо, очень плохо») — это отсутствие замера, а не запрет** («ложные срабатывания — это плохо, очень плохо»); предусловие — строки 295 и 12. ⚠ **Сюда же перенесён 06.09 «ДЕТЕКТОР ВЕРНОСТИ ЗНАЧЕНИЯ» из строки 318** — четвёртым носителем одного вопроса он был бы трекерной инерцией: прибор, проверяющий вложенный `dst` ПО ИСХОДНИКУ, — тот же самый, что линза строки 319 после починки, а $0-прототип уже назван строкой 12. ⇒ **строка 318 остаётся только конкретной правкой** (комментарий постчека привести к поведению плюс пин), а вопрос «чем ловить неверное ЗНАЧЕНИЕ» живёт здесь и упирается в замер точности, а не в код. ⛔ **ПРИОРИТЕТ №1 ВЛАДЕЛЬЦА («100% консистентность») НЕ ИСПОЛНЯЕТСЯ КОДОМ И ПРОТИВОРЕЧИТ ДЕЙСТВУЮЩЕМУ ПОРОГУ.** Найдено ревизией документации 05.09. Три расхождения, каждое с носителем: **(1) ПОРОГ.** `docs/architecture/02-mvp-plan.md` и реестр `D10` держат «≥98%» — владелец 05.09 сказал **100%** (`D39.198`). Два процента на книге в тысячи терминов — это десятки разъехавшихся имён. **(2) МЕХАНИЗМ.** Единственный сегодняшний носитель консистентности — флаг `glossary_miss` РАНГА 5, то есть замечание, **с которым текст ОТГРУЖАЕТСЯ** (`backend/internal/pipeline/status.go` + `disposition.go`, греп `FlagGlossaryMiss`). Владелец сказал «разъехавшийся термин — СТОП». Флаг стопом не является. **(3) СЕМАНТИКА.** Приоритет №2 («никаких выдуманных сюжетных линий и смыслов») не имеет носителя вовсе: в реестре требований такого ПТ нет, ближайшее — гейт по ДЛИНЕ, а не по смыслу; семантический судья в движке не построен (слой 5). ⇒ **Сессия качества, собранная по нынешним докам, построит от неверной цели.** ⚠ Родня: строка **267** (две конкурирующие формы одного термина доезжают до редактора) — она и есть живой экземпляр нарушения приоритета №1 | бэкенд+полигон | скоро | порог 100% в носителях · консистентность как СТОП, а не флаг · носитель для приоритета №2 | ревизия документации 05.09, `D39.198` | +| 287 | **ТЕСТ ИСЧЕРПАЕМОСТИ ФЛАГОВ СЛЕП НА ТРЕТЬЮ ЛЕГАЛЬНУЮ ФОРМУ Go — найдено ПОСАДКОЙ верификатора приёмки, не автором.** Тест читает объявления причин через `go/ast` и покрывает две формы (`X FlagReason = "…"` и `X = FlagReason("…")`), о чём говорит его собственный комментарий «BOTH GO SPELLINGS COUNT». Третья форма — типизированная спека со значением-конверсией (`const X FlagReason = FlagReason("…")`) — **ПЕРЕЖИВАЕТ посадку**: типизированная ветка ждёт `*ast.BasicLit`, получает `CallExpr`, `lit == nil` и молча продолжает. Пол `found < 15` её тоже не ловит. ⚠ **Это ГРАНИЦА, а не живая дыра:** ни одной такой формы в дереве сегодня нет (все константы в `disposition.go` типизированные) — но комментарий обещает больше, чем тест держит, а это тот самый класс «утверждение шире ветки», который пак ловил четырежды. Там же не назван и `var`-случай. | бэкенд | когда-нибудь | покрыть третью форму ЛИБО сузить комментарий до двух | верификатор приёмки 05.09, посадка вне списка автора | +| 288 | ⛔ **«ПОПРАВИЛ ЧИТАТЕЛЯ, ОСТАВИЛ ПИСАТЕЛЯ» — ЕЩЁ ОДНО ПОЛЕ РЯДОМ, и оно бьёт в цель №2.** Сессия прибила читателя `classifyInputFor` и писателя `SetSourceScripts`; СОСЕДНЯЯ строка того же `defer` в `loadLangPack` — `backend/internal/pipeline/runner.go`, греп `CompileCheckersFor(r.pack, lang.TargetChecksFor` — не прибита ничем. **Предъявлено посадкой верификатора:** подмена `TargetChecksFor(r.Book.TargetLang)` на `TargetChecksFor("ru")` оставляет ВЕСЬ пакет `pipeline` зелёным (`ok 65s`). ⇒ Книга на →ja с включённым санитайзером компилировала бы РУССКИЕ паттерны читаемости: ложные `sanitizer_defect`, а ложный флаг ЭСКАЛИРУЕТ — это платные хопы за здоровый текст. От этой строки зависят `TargetActive()`, ёфикатор и латинский гард. Пин строится тем же двухкнижным приёмом, что и у `SourceScripts` | бэкенд | скоро | пин писателя целевых чекеров двумя книгами | верификатор приёмки 05.09, посадка вне карты отчёта | +| 289 | ⛔ **ДВЕ ВЕТКИ `CheckKeys` ДАЮТ ПРОТИВОПОЛОЖНЫЙ ОТВЕТ НА ОДИН И ТОТ ЖЕ КОНФИГ, а новый тест закрепляет лейбловую на фикстуре, где её собственная посылка ЛОЖНА.** Безлейбловая ветка требует ключ хопа ТОЛЬКО при `Escal.BudgetUSD > 0` (и это ратифицировано комментарием); лейбловая берёт `ReachableModels()`, куда `ResolvedHop` попадает БЕЗУСЛОВНО. При бюджете 0 хоп в рантайме не стреляет никогда. Зонд верификатора: одна стадия с `escalate_to` на провайдере без ключа, бюджет 0 ⇒ безлейбловая `nil`, лейбловая `missing API keys`. ⚠ Что внёс `74ffe4f`: кейс «the stage's escalation hop» и `why` записи `WB65` («a labelled run CALLS its escalation hop») стоят на фикстуре БЕЗ бюджета — то есть тест ПИНИТ требование ключа для модели, которую этот прогон вызвать не может. **Зеркало класса, который пак сам и нашёл: пин на «достижима» не есть пин на «вызывается».** Лечится либо бюджетом в фикстуре, либо приведением веток к одному правилу | бэкенд | скоро | свести ветки к одному правилу ЛИБО починить посылку фикстуры | верификатор приёмки 05.09, зонд вне карты | +| 290 | **ARM 1 нового теста банкноты проходит ВАКУУМНО, если каталог пары переедет — класс `WB41`, названный самой сессией.** Тест вписывает `langpack_root`, но не проверяет, что пак ЗАГРУЗИЛСЯ (`r.pack != nil`). Предъявлено: с несуществующим корнем все три плеча зелёные, а посадка `WB58` (снятие плеча контраста) **ПЕРЕЖИВАЕТ**. То есть красный `WB58` держится не тестом, а наличием каталога на диске. Лечение — посылка о состоянии пака в самом тесте. ⚠ Тот же класс: **тест исчерпаемости флагов слеп ещё на ДВЕ формы** сверх найденной первым верификатором — `var X = FlagReason("…")` на уровне пакета и `const` ВНУТРИ тела функции: обе посадки прошли, ни пол `found < 15`, ни сверка с картой не сработали (объявлено 17, найдено 16, карта 16). Итого форм пять, тест держит две, комментарий обещает «обе» | бэкенд | скоро | посылка о загрузке пака + покрыть или сузить обещание исчерпаемости | верификаторы приёмки 05.09 | +| 291 | ✅ **РЕШЕНО ВЛАДЕЛЬЦЕМ 05.09 (`D39.204`): деградировать во ФЛАГ, отличный по причине от исчерпания регенераций; текст попытки 0 оплачен и отгружается, волна идёт дальше. Вариант «минимальная покупка ≥ `step_max_usd`» СНЯТ — он стоил бы покупателю входного порога в пять глав. ⚠ Работа СВОИМ паком движка (правка пути ошибки в `stagerun.go` + новая причина флага + пин «купленное доставлено ⇒ не `exit 4`»), в принятый пак не дописывается.** ⛔ **ОБЯЗАТЕЛЬСТВО, БЕЗ КОТОРОГО ПАК НЕПОЛОН: новая причина флага выходит ОДНИМ АКТОМ С ПЛАТФОРМЕННОЙ ПОЛОВИНОЙ.** Карта заметок платформы РУКОПИСНАЯ (`platform/internal/ingest/notes.go`) и уезжает независимо от словаря движка; цена несделанного замерена — `PD-246`/эррата 04.09-в: минор 0.10.0 сутки жил ЛОЖНЫМ на проводе, причина доезжала читателю как `unspecified`, поймала это зона своей пере-проверкой ПОСЛЕ слов оркестратора «приёмка закончена». ⇒ промт этого пака обязан назвать ОБЕ зоны, а акт — предъявить зеркало. ⚠ Записано СТРОКОЙ, а не каналом, по слову сдавшей зоны: «`/tmp/textmachine-channel` не переживает рестарт — это в него и заложено», и обязательство, живущее в переписке двух сессий, умирает вместе с ними. ⚠⚠ **НИЖЕ — ИСТОРИЧЕСКИЙ РАЗБОР, ПО КОТОРОМУ РЕШАЛИ; как ЖИВОЕ не читать.** Его фраза «ВЫБОР НЕ СДЕЛАН» противоречит голове этой же строки — выбор СДЕЛАН владельцем (`D39.204`). ⛔ И ссылка «смена `D2.3`» в нём НЕВЕРНА ДВАЖДЫ, проверено по телу ноты (`../archive/architecture/05-decisions-D1-D38.md`, греп `^## D2. Диспозиция`): **(1)** `D2` уже кончается флагом («ретрай с бо́льшим `max_tokens` до капа, потом флаг») ⇒ это ДОСТРОЙКА, а не смена; **(2)** `D2.3` — по правилу подномеров ПУНКТ 3 тела `D2`, то есть «детектор вырождения перед удвоением `max_tokens`», к деградации отказа резервации отношения не имеет. **Настоящий адресат — `D2` п.2 «Тегировать `flag_reason`»**, и он делает вывод СИЛЬНЕЕ: тегирование причины там уже ТРЕБУЕТСЯ ⇒ новая причина есть **новый тег под существующим правилом**, а требование «причина обязана отличаться от исчерпания регенераций» — не добавка к канону, а его ИСПОЛНЕНИЕ. ⚠ Голова и хвост одной строки противоречили друг другу о состоянии решения — тот же класс, что находка `F7` приёмки, только не в коде, а в бэклоге; поймала сдавшая зона движка уже после закрытия своего пака. **ОТКАЗ РЕЗЕРВАЦИИ НА РЕТРАЕ НЕ ДЕГРАДИРУЕТ И НЕ ОСТАВЛЯЕТ СЛЕДА — юнит может заклинить НАВСЕГДА, а волна не может продолжиться без дыры.** `maxTokensForAttempt` удваивает бюджет на каждой регенерации (`backend/internal/pipeline/disposition.go`, греп `maxTokensForAttempt`), так что attempt 1 резервирует вдвое больше attempt 0. Отказ ретрая уходит наверх из цикла попыток (`backend/internal/pipeline/stagerun.go`, греп `return nil, err` в цикле попыток) **РАНЬШЕ `UpsertChunkStatus`** ⇒ чекпойнт attempt 0 есть (реплей за $0), **строки `chunk_status` НЕТ**, читающие модели видят юнит как `pending`, экспорт не отдаёт ничего. **Следствия два.** (1) Если потолок покупки не вмещает attempt 1 — юнит не доделается НИКОГДА: каждый резюм реплеит attempt 0 за $0 и умирает на attempt 1, прогон уходит exit 4 при ПОЛНОСТЬЮ доставленных купленных юнитах. (2) Продолжить волну после отказа ретрая нельзя без ДЫРЫ в непрерывном префиксе — то есть цена глобальной защёлки (недодача юнитов, которые влезали; разброс резервов внутри волны замерен ×2.976) различителем «свежий/ретрай» НЕ снимается. ⚠ **Оркестратор предлагал такой различитель на посылке «ретрай оставляет ФЛАГОВАННЫЙ юнит» — посылка ЛОЖНА, опровергнута зоной по строкам.** **Два пути лечения, ВЫБОР НЕ СДЕЛАН:** (а) отказ ретрая деградирует во флаг attempt 0 — смена `D2.3`, закрывает ОБА следствия; (б) минимальная покупка платформы ≥ `step_max_usd` движка (он включает ретраи именно поэтому) — закрывает только (1) и стоит продукту минимальной покупки ~5 глав | бэкенд+платформа | скоро | выбор владельца между (а) и (б) + пин | бэкенд-сессия денежного стопа 05.09, формулировка зоны | +| 292 | ⛔ **ЧЕСТНОСТЬ ТРЁХ СТРОК НАБЛЮДАЕМОСТИ — ЖИВАЯ ПОЛОВИНА (б) ЗАКРЫТОЙ СТРОКИ 105, заведена 05.09 отдельным носителем.** Закрытие 105 сняло только половину (а) — предикат `isBankRole`; половину (б) чинить никто не заказывал, а на неё ссылались ДВА носителя как на «до фикса 105». Три дефекта, все воспроизведены: **(1)** строка `VOICE` берёт `rules=` из конфига ВРЕМЕНИ ОТЧЁТА (`backend/internal/pipeline/quality.go`, греп `rules=`), поэтому включение `gates.voice` ПОСЛЕ прогона печатает «измерено, чисто» для книги, которую никто не мерил; **(2)** та же строка печатается при ВЫКЛЮЧЕННОМ гейте, если `SpoilerLeaks>0` — поведение верное, неверна формулировка отчёта; **(3)** знаменатель `BANKNOTE` = `len(states)` вместе с призрачными строками `retrieval_state`, тогда как соседний агрегатор их фильтрует ⇒ после пере-чанковки покрытие ЗАНИЖАЕТСЯ. ⚠ Цена молчания прямая: отчёт говорит «измерено», когда не мерили, — это ложь читателю в том самом месте, куда смотрят, решая, готова ли книга. Печатает `cmd/tmctl/render.go` (греп `rules=`), пин — `render_observability_test.go`. | бэкенд | скоро | правка формулировки + знаменателя + тест на «включил гейт после прогона» | D39.86, D39.200; археология — `architecture/13-tech-debt-anchors.md` §Б-105 п.(б) | +| 293 | ⛔ **ФАЙЛ ПОД ЛЮБЫМ КАТАЛОГОМ `books/` НЕВИДИМ ДЛЯ GIT — `git status` его не показывает, `git add` молча не берёт, и сдающая зона теряет работу, не заметив.** Предъявлено 05.09 платформенной сессией и проверено оркестратором до лендинга: `git check-ignore -v platform/internal/books/counter_test.go` → `/info/exclude:9:books`. **Причина: правило `books` в `.git/info/exclude` НЕЯКОРЕНО**, а gitignore без ведущего `/` ловит каталог с этим именем на ЛЮБОЙ глубине. ⚠ Неякорность ОСМЫСЛЕННА и снимать её нельзя не думая: `books` в связанном рабочем дереве — СИМЛИНК, а трекнутое правило `/books/` матчит только каталоги (комментарий стоит там же). ⚠ **Почему это не поймал никто:** тронутые файлы того же каталога в `git status` ВИДНЫ (игнор действует лишь на неотслеживаемое), поэтому пропажа не читается глазами; а `git commit -- <путь>` untracked роняет и без игнора. Замер: без `git add -f` уехал бы 31 файл из 32. **Лечение — не «поправить exclude»:** файл ОБЩИЙ для всех рабочих деревьев клона, включая полигонное, и менять семантику игнора под живыми сессиями нельзя. Формы, между которыми выбирать: (а) якорить правило под КОНКРЕТНЫЙ симлинк (`/books` в корне дерева) и проверить, что симлинк по-прежнему игнорируется во ВСЕХ деревьях; (б) оставить как есть и завести проверку лендинга — `git status --ignored --short <зона>` перед каждым актом. | оркестратор | скоро (гигиена лендинга, $0) | выбор формы + проверка во всех воркtree | предъявлено платформенной сессией 05.09; проверено исполнением при лендинге `7e2226a` | +| 294 | ⭐ **ФОРМА «СКОЛЬКО ДОБАВИТЬ» — решение владельца 05.09, ратифицировано `D39.203`.** Наружу вместо «сколько не хватило на ЭТОТ вызов» едет **«сколько добавить, чтобы прошёл ЛЮБОЙ следующий»** = `max(shortfall, step_max − headroom)`: сегодняшняя недостача закрывает текущий вызов, а следующий может быть крупнее, и человек доплачивает дважды. ⚠ **НЕ однострочник, и объявлять его дешёвым было бы ошибкой** (зона дешевизну не подтвердила): новая величина · **ПЕРЕИМЕНОВАНИЕ поля** — `shortfall_micro_usd` станет ложным именем, кандидат `top_up_micro_usd` · минор `StreamVersion` 1.3→1.4 · зеркало словаря у платформы · пере-снятие пина белого списка кадра `ceiling`. ⚠ Построенное поле НЕ ложно, оно у́же: закрывает вызов, а не следующий шаг | бэкенд+платформа | скоро | новая величина + переименование + минор потока | **D39.203**; тензия п.(3) против п.(4) заказа найдена зоной движка | +| 295 | ⛔ **СНАЧАЛА ПОДАТЬ ПОДПИСАННЫЙ КАНОН В ПРОГОН — только потом мерить точность чекера и решать про гейт.** Живая дыра приоритета №1 владельца («100% консистентность») — НЕ порог и НЕ флаг: канон из 53 подписанных терминов **не подключён к стенду**, весь замеренный дрейф — дрейф С ОТКЛЮЧЁННЫМ каноном, а там, где его подключали, консистентность 99.3–100%. ⇒ мерить полноту чекера на прогоне без канона значит мерить не то. **Порядок:** (1) канон в прогон · (2) пере-замер точности/полноты (строка **12**, прежний замер порочен — класс одного иероглифа не имел ни одного положительного примера) · (3) решение владельца по `gates.glossary.postcheck_gate`. ⚠ Владелец 05.09: «если он ложно положительно будет стрелять это плохо, очень плохо» ⚠ **ПОЛОВИНЫ НАЗВАНЫ 06.09 по ревью напарника — прежде тут стояло «назвать или отдать», и это переезжало бы следующей смене той же инерцией.** **(а) Полигон/владелец:** подать канон в стенд-книгу — это ДАННЫЕ (сид-YAML либо решения `bank-apply`) ПЛЮС платный прогон под санкцией; у бэкенд-сессии нет ни книги, ни стенда, ни денег, поэтому половина её не является. **(б) Бэкенд — только ВОПРОСОМ, а не задачей:** умеет ли сид-путь нести подписанный статус; если нет — это пинг оркестратору, и тогда появляется бэкендовая работа. ⇒ зона ведущая — полигон. | полигон (бэкенд — по вопросу) | скоро | подача канона + замер | **D39.205**, D39.198 п.3-4, строка 12 | +| 296 | **ТОЧЕЧНАЯ ПЕРЕГЕНЕРАЦИЯ ПО ПРОМАХУ ГЛОССАРИЯ — направление владельца 05.09 («или флагать, или перегенерировать проблемный участок»), работы сегодня НЕТ.** Актуаторы ремонта — только `RepairLatinResidue` и `RepairBrokenWord` (`backend/internal/pipeline/repair.go`, греп `defaultRepairClasses`); `glossary_miss` нет ни там, ни в `knownRepairClasses`. Сегодняшние лекарства не точечные и обе дороги: удержать ВЕСЬ фрагмент (гейт) либо править глоссарий с `--resnapshot`, то есть ПЕРЕ-ОПЛАТИТЬ книгу. ⇒ заказ: `glossary_miss` как класс-актуатор — перегенерация участка с подписанной формой. ⚠ Гейтится строкой **295**: без замера точности перегенерация по ложному срабатыванию перепишет верный текст | бэкенд | когда-нибудь (после 295) | новый класс актуатора + пост-инвариант | **D39.205** | +| 297 | ✅ **ПЕРВАЯ ПОЛОВИНА ИСПОЛНЕНА ЛЕНДИНГОМ 06.09 (`2f65d1d`, акт `D39.210`): словарь получил четвёртое значение `delimited`**, и spine-EPUB вместе с `\f` в txt больше не выдаются за слово формата. ⛔ **ВТОРАЯ ПОЛОВИНА ТЕПЕРЬ ОБЯЗАТЕЛЬНА, А НЕ ЖЕЛАТЕЛЬНА:** временное правило платформы «`declared` вести как `none`» после лендинга начинает ОТНИМАТЬ ползунок глав у книг, чья структура объявлена настоящим `nav`/NCX — то есть молча недодавать продукт. ⚠ **Якоря прежней редакции этой строки указывали на текст, который пак УДАЛИЛ, а якорный линт этого НЕ ВИДЕЛ** — они были без токена, файл длинный, адрес «разрешался». Живая рабочая строка протухла молча; класс несёт строка **306**, и это его первый пойманный случай в рабочей строке, а не в архиве. ⚠ **Тело прежней редакции СНЯТО 06.09, а не оставлено под шапкой** — оно цитировало рекламу «how much the chapter cut can be trusted» как живую улику, а пак её УДАЛИЛ (`grep -c` → 0), и три его якоря целили в текст, которого нет: словарь уехал, а `:94-95` попал в структуру, введённую дофиксом. То есть строка утверждала про себя, что она первый пойманный случай «якорь протух молча», и одновременно продолжала им БЫТЬ; поймал это строитель пака грепом, линт был зелён. **Что стало вместо снятого:** словарь живёт на `backend/internal/chunk/ingest.go:125-149`=`WHICH PATH drew the chapter boundaries` — четыре значения, и первая же строка комментария теперь говорит про ПУТЬ, а не про доверие. Прежняя двусмысленность («поле отвечает на провенанс, а рекламирует доверие») **устранена паком, а не описана** | бэкенд+платформа | скоро (структурный пак) | недостающее значение на проводе, и `declared` означает ТОЛЬКО объявленную форматом структуру глав | **D39.202**, D39.205 | +| 298 | ⛔ **`unit_resolutions` КЛЮЧЕВАНЫ ПОЗИЦИЕЙ, И ЛЮБОЙ ПЕРЕКРОЙ ИХ СНОСИТ ЦЕЛИКОМ.** Ключ `(book_id, chapter, unit, wave)` позиционен по построению, и миграция это прямо объявляет: «keyed by the ENGINE's own ordinals» (`platform/internal/pgstore/migrations/00015_seam_ceiling_and_units.sql:50-56`); событие `unit_done` несёт номер главы и ординал юнита, синк пишет их как есть (`platform/internal/pgstore/sink.go:249`). Потому при перекрое платформа ОБЯЗАНА удалять решения — иначе они перевесятся на чужую главу. Сегодня цена нулевая: решения есть только у стенд-книги, и это окно закрывается с каждой новой платной книгой. ⇒ разрешать `(chapter, unit)` в идентификатор ПРИ ПРИЁМЕ события, пока дерево у платформы на руках, и хранить идентификатор. Платформенная половина структурного пака: миграция плюс синк. ⚠ Этой строкой НЕ закрывается одноразовая перечеканка всех id при смене смысла `cutTag` — это другой предмет и другая цена | бэкенд+платформа | скоро (структурный пак) | решения переживают перекрой, не переклеиваясь на чужую главу | **D39.202** | +| 299 | ⛔ **ИМЯ В GO-КОММЕНТАРИИ, КОТОРОЕ НИ ВО ЧТО НЕ РАЗРЕШАЕТСЯ, — И НИЧТО ЭТОГО НЕ ЛОВИТ.** ⭐ **ЗАМЕР 05.09, полностью меняющий форму ДОРОГОЙ половины (той, что сверяет имя с каталогом мутаций): она обязана писать ФАЙЛ, а не читать `stdout`.** Полный прогон каталога дал: несущих верхнеуровневых тестов **189** из 1213 тест-функций движка (**15,5 %** батареи; ⚠ испр. 06.09 автором замера: было «194 / 16,0 %» — его парсер резал вывод по запятой, а пять подтестов несут запятую В ИМЕНИ, и круглые «16,0 %» получились именно из пяти фантомов. ⚠ Числитель и знаменатель разной природы: 1213 считает только `^func Test`, а один из 189 — `Fuzz`; честно 188/1213 либо 189/1219, но не 189/1213), и **139 записей из 197 пинятся РОВНО ОДНИМ тестом** — то есть краснота атрибутируется однозначно, и долговременная запись «какие тесты несущие» реально получается. ⛔ **Но тул обрезает список имён на четырёх и печатает `+N more` — так усечены 9 записей из 197, и механизм, читающий `stdout`, насчитал бы 178 вместо 194 И НЕ УЗНАЛ БЫ ОБ ЭТОМ.** Это тот же класс «прибор ответил на свой вопрос»: величина ВЫЧИСЛЯЕТСЯ сегодня, но в поток приезжает УСЕЧЁННОЙ. ⇒ вход механизма — `-logs`, не вывод. Точный список имён воспроизводится пере-прогоном каталога с `-logs`; сохранять его отдельным артефактом не нужно. Два живых носителя, найдены верификацией 05.09 (`D39.207` п.3): **(а)** `backend/internal/runevents/runevents.go:187`=`not to a screen` цитирует **СТАРЫЙ** путь — `docs/BACKEND_MONEYSTOP_SESSION_PROMPT.md`, строка 78 (записано БЕЗ формы якоря намеренно: это УЛИКА мёртвой ссылки, а не ссылка; в форме якоря линт вечно краснел бы на предмете самой записи) — и удалён именно он (промт уведён в архив коммитом `f71c4dc`, тем же, что писал акт), а цитируемая фраза ЖИВА в архивной копии и стоит там на строке **82**. ⚠ **Испр. 06.09: клауза была заландена ПЕРЕВЁРНУТОЙ** — называла удалённым архивный файл, который цел, и приписывала комментарию цитату, которой в нём нет. Механика ошибки записана отдельно, она повторяемая: сплошная замена строки якоря при пере-наведении попала в ОПИСАНИЕ дефекта, где тот же путь был УЛИКОЙ, а не ссылкой, и превратила описание поломки в описание её отсутствия. Нашёл верификатор `textmachine-main-e6` контролем закрытия своих же находок; ⚠ приёмочный столбец строки при этом сформулирован ВЕРНО и поймал бы дефект независимо от прозы — то есть major в описании, не в гейте; **(б)** `backend/internal/config/internal_call.go:11`=`builds a Stage outside the loader` и `backend/internal/pipeline/live_reprobe_test.go:14`=`the single-egress guard` называют сторожами тесты `TestSyntheticStageSeamIsSingle` и `TestProviderEgressSeamIsSingle`, которых в дереве НЕТ — инварианты при этом реально сторожатся вет-анализаторами `StageSeam`/`EgressSeam` (`backend/internal/archguard/archguard.go:80,377`=`StageSeam, RequestSeam, EgressSeam`), то есть гарантия цела, а назначенный ей сторож ВЫДУМАН. Замер верификатора: из 2026 упомянутых в Go имён `Test…` определены 2012; из восьми неразрешающихся четыре — не дефекты (надгробия и иллюстрация), два — мелочь, два — эти. ⇒ **дешёвая половина открытого вопроса `D39.202` п.9: не «доказал ли каталог, что названный тест умеет падать» (дорого, требует интеграции с `tmmutate`), а «РАЗРЕШАЕТСЯ ли названное имя вообще» — это греп, и сегодня он находит два дефекта.** ⚠ `counts.py --lint` этого класса не видит по построению: он читает доки, а не код. ⚠⚠ **ДВА ПРАВИЛА, БЕЗ КОТОРЫХ ГЕЙТ ВЫКЛЮЧАТ НА ВТОРОЙ ДЕНЬ** (принесены верификатором вместе с находкой): **(1)** разрешением считается и ПРЕФИКС — доки и комментарии цитируют имя усечённым, как греп-цель; **(2)** НАДГРОБИЯ не дефект — комментарий, прямым текстом говорящий «удалён/заменён», законен, как и иллюстративное имя в примере. Замер, обосновывающий оба: из восьми неразрешающихся имён СЕГОДНЯ четыре — надгробия и иллюстрация, два — усечение в шапке над функцией, и лишь два — настоящие выдуманные сторожа. Гейт без этих правил краснеет 8 из 8, то есть врёт вчетверо, и его погасят — ⚠⚠ **и ЗАМЕР 06.09 показал, что для указателей `путь:строка` в Go арифметика ХУЖЕ, а потолок дешёвой половины НИЖЕ, чем считалось.** Всего таких указателей **36**; настоящий дефект среди них **ОДИН** (`runevents.go:187`, уже назван выше). Остальное: **5 целят ВНЕ репозитория** (стандартная библиотека Go, `yaml.v3`, jieba) — внутрирепозиторный линт их проверить не может в принципе; **~7 разрешаются НЕОДНОЗНАЧНО** — голое имя файла имеет от двух до восьми одноимённых кандидатов. ⇒ наивный гейт покраснел бы примерно **двенадцать раз ложно при одном настоящем дефекте**. ⛔ **ДВА правила записать ДО заказа, иначе гейт врёт впятеро и его выключат:** **(1)** внешняя цель — НЕ дефект (путь, не разрешающийся в дереве и опознаваемый как чужой, исключается); **(2)** ⛔ **у голого имени файла SOUND-ДЕФОЛТА НЕТ — гейт обязан считать его НЕПРОВЕРЯЕМЫМ (skip), а не угадывать.** ⚠ Прежняя редакция этого пункта предлагала конвенцию «сперва каталог цитирующего файла, затем модуль, затем корень» — **и она ОПРОВЕРГНУТА 06.09 её же автором**: для дока, цитирующего КОД, каталог цитирующего файла систематически неверен, потому что рядом с доком лежат другие ДОКИ. Контрпример — `PROGRESS.md:71` → `README.md:95`: конвенция даёт `docs/README.md` (41 строка) и вердикт «протух», а автор имел в виду `backend/README.md`, где строка 95 **та же, что в минуту написания**. В дереве `README.md` четырнадцать штук. ⇒ гейт с конвенцией краснел бы именно на ЖИВЫХ якорях. Хочешь проверяемости — пиши путь или токен. ⚠ И третье, важнее обоих: **НИ ОДИН из 36 не несёт токена**, поэтому ДОРОГАЯ половина упирается не в инструмент, а в то, что сверять нечего; дешёвая остаётся верным первым шагом, но её потолок теперь измерен — **один дефект на тридцать шесть**. а гейт умирает не отключением, а вытеснением из привычки (`D39.202` п.3-бис) | бэкенд | скоро | грепом: имя `Test…` и `<док>.md:<строка>` в Go разрешаются, иначе красно | **D39.207**, D39.202 | +| 300 | ⛔ **РЕПО-ШИРОКИЙ СТОРОЖ НЕ ДОТЯГИВАЕТСЯ ДО СОСЕДНЕГО ВОРКРИ НА ДРУГОЙ ВЕТКЕ — и стенд от этого УЖЕ СГНИЛ.** ⚠ Замер 05.09, вторая половина: снять пин манифеста стенд-конфигами удалось для **ОДНОГО исходника из восьми**; семь падают, и ни одно падение не про структурный пак. Причины — ретированные в `main` вещи, живые в дереве `polygon`: плейсхолдер `{{genre}}` (ретирован `D39.138` п.2в) — в моём дереве `grep -rln '{{genre}}' backend/prompts/` ПУСТ, в соседнем живёт в ШЕСТИ файлах промтов, и падают на нём 6 конфигов из 8; поля `stm_depth`/`overlap_tokens`, которых больше нет в `config.ContextAssembly` — 1 из 8; ключи `mined_delta:`/`mined_rejects:` (ретированы `D39.156` п.3) — **17 конфигов из 31**. ⭐ **Тест `genre_retired_test.go:46` предсказал этот случай дословно** («should be caught by the repository that retired it, not by a paid run») — и поймали его действительно бесплатно, но **сторож не дотянулся до соседней ветки**, где ретированное живо. ⇒ общая форма дефекта: ретирование, проведённое репо-широким гейтом, НЕ распространяется на воркри другой ветки, и стенд тихо остаётся в прошлом. **ЧАСТНЫЙ СЛУЧАЙ ТОГО ЖЕ КОРНЯ — ДАННЫЕ ПАР-ПАКА В ДВУХ ВЕТКАХ.** Замер бэкенд-сессии 05.09 по 31 конфигу `book.yaml` стенда 蛊真人: у **20** `langpack_root` указывает в СОСЕДНЕЕ РАБОЧЕЕ ДЕРЕВО `/home/ubuntu/projects/textmachine` — а оно на ветке **`polygon`**; у 9 — в `main`; 2 не объявляют его вовсе. Пока каждая ветка собирается из своего дерева, расхождения не видно. ⚠ **Структурный пак (`CHAPTER_STRUCTURE_SESSION_PROMPT.md`) выносит `marker`/`units` из `zh-ru/heading.txt` в данные ИСТОЧНИКА и учит `parseHeading` ОТВЕРГАТЬ эти ключи с переходным сообщением** ⇒ старый файл, оставшийся на `polygon`, станет невалидным, и двадцать конфигов не загрузятся вовсе (загрузка пар-пака FAIL-LOUD). **Выстрелит НЕ при лендинге в `main`, а в момент, когда полигон вольёт `main` в свою ветку** — то есть цена назначена чужой зоне и в чужой момент. ⇒ заказ: перед мержем полигон либо снимает `marker`/`units` из своего `heading.txt`, либо переводит `langpack_root` своих конфигов на `main`. ⚠ Второе дешевле и, возможно, правильнее по существу: **каталоги `configs/langpacks` в обоих деревьях сегодня БАЙТ-В-БАЙТ идентичны** (`diff -rq` пуст, sha256 `heading.txt` совпадают), а комментарии в конфигах, утверждающие «`ru/` есть только здесь», ПРОТУХЛИ — класс строки 299. То есть двадцать конфигов смотрят в чужую ветку по причине, которой больше нет | полигон | скоро (до мержа main в polygon) | конфиги грузятся после мержа, либо `langpack_root` переведён | **D39.207** | +| 301 | ⛔ **`--max-units` НЕ УМЕЕТ СКАЗАТЬ «ДОРАБОТАЙ ПЕРЕНЕСЁННОЕ И НЕ НАЧИНАЙ НОВОГО», И ЧЕЛОВЕК ЗА СВОИ ДЕНЬГИ ПОЛУЧАЕТ НЕ ТУ РАБОТУ.** Флаг бюджетирует N НОВЫХ стартов, а carried-юниты (задрафченные прошлым прогоном и не отгруженные) движок допускает СВЕРХ гранта, до N штук: `granted()` их не считает (`backend/internal/pipeline/volume.go:396-407`), и собственный тест движка это фиксирует — под `--max-units 1` при одном carried выходит `Delivered=2, Carried=1` (`volume_test.go:721`). ⇒ прогон, оборвавшийся МЕЖДУ волнами (стоп на подпись банка, деплой, краш), при респауне получает `--max-units = заказ − доставлено`, и движок оплачивает ЧЕРНОВИКИ глав, которых человек НЕ ЗАКАЗЫВАЛ, раньше редактуры заказанных. ⚠ **Это НЕ перерасход** — `--ceiling-usd` держит сумму; ломается ровно обещание «вы купили N»: за те же деньги приходит другая работа. Выразить нужное платформа не может по построению: вычесть carried значит обнулить грант, а ноль для движка = «без границы» (`planVolume` при `MaxUnits <= 0` возвращает `nil`, `volume.go:321`). ⇒ заказ: словарь скоупа обязан различать «сколько НОВЫХ начинать» и «сколько всего допускать». Живая половина **эрраты 03.09-а** (перенос юнита вне гранта, семантика НЕ ратифицирована, слово владельца «подумаем»), но со следствием более острым, чем записано в ноте: там был перерасход единиц, здесь — подмена предмета покупки | бэкенд+платформа | скоро | флагом выражается «ничего нового не начинать»; пин на респауне между волнами | **D39.207** | +| 302 | **РЕЗКА xhtml ПО ЯКОРЯМ `nav`: текст цел, ГРАНУЛЯРНОСТЬ ТЕРЯЕТСЯ.** Массовая форма EPUB — несколько глав в ОДНОМ документе, разделённых якорями, и `nav` объявляет на них отдельные цели. Структурный пак 1 такие цели СХЛОПЫВАЕТ: одна глава вместо трёх, текст не теряется (формулировка бэкенд-сессии 05.09: «текст цел, гранулярность потеряна»). ⚠ **Ложь при этом уже не едет** — тем же паком ратифицировано: схлопнулась хоть одна цель ⇒ книга НЕ `declared`, а `delimited`, плюс счёт `targets collapsed: N` в WARN. То есть провенанс честен, а разрез груб. ⇒ заказ: резать документ по якорям целей. ⛔ **Почему НЕ сделано паком 1 и почему это дорого:** это единственное место, трогающее `extractXHTML`, у которого **четыре пина байт-паритета** (`ingest_test.go:323, 359, 423, 467` — void-теги, несбалансированный ruby, raw-text-элементы, голый амперсанд), и ошибка там ТИХАЯ. Заходить в него в конце пака, ради гранулярности, при живом гейте разреза — плохой размен. ⚠ Строкой закрывается ГРАНУЛЯРНОСТЬ, а не провенанс: продать такую книгу по главам платформа и так не предложит | бэкенд | когда-нибудь (после пака 2) | книга с тремя якорями в одном документе даёт три главы; четыре пина байт-паритета целы | **D39.207** | +| 303 | **НЕ-CJK ПУТЬ ПОСТРОЕН НАПОЛОВИНУ: чанкер безъюнитную грамматику УЖЕ УМЕЕТ, ингест по ней НЕ РЕЖЕТ.** `detectChapterUnit` итерирует `UnitOrdered` и без юнита возвращает 0 ⇒ грамматика вида «Kapitel 12» / «Chapter 12» (маркер + номер, БЕЗ юнита) книгу не режет; при этом `matchHeaderLine` чанкера юнита не требует и на это есть живой тест (`TestStripHeadingGenericLatinMarker`). То есть заголовок такой книги движок умеет СНЯТЬ, но не умеет по нему РАЗРЕЗАТЬ. ⇒ ревью-вопрос проекта «заработает ли пара, которой в репо НЕТ, без правки Go» закрыт для языков С ЮНИТОМ (доказано сквозным тестом `TestANewLanguageCutsFromItsDataFileAlone`: без файла корейская книга — одна глава, с `ko/structure.txt` — три, разница только в данных) и **ОТКРЫТ для языков без юнита**. Это названный ВХОД в пак 2, а не открытие по ходу. ⚠⚠ **ГРАНИЦА ЗАМЕРА, названная самой зоной и записанная здесь в её настоящей силе:** утверждение проверено **ПО КОДУ и ПО ТЕСТУ НА ФИКСТУРЕ**; **живая не-CJK книга через ингест НЕ прогонялась**. «На живой книге» под этой строкой НЕ стоит, и ссылаться на неё как на замер живого поведения нельзя | бэкенд | скоро (вход пака 2) | безъюнитная грамматика режет книгу; замер на живой не-CJK книге | **D39.207** | +| 304 | ⚠ **РИСК NULLABLE ДЕНЕЖНЫХ КОЛОНОК — НЕ ТЕОРЕТИЧЕСКИЙ, А ОТЛОЖЕННЫЙ, и это вскрыла ЛОЖНАЯ ПРИЧИНА в отчёте зоны.** Платформенная зона объяснила чистый `sqlc diff` тем, что новые колонки лежат «в таблицах, для которых sqlc не держит запросов» — **догадка, и неверная**: `queries/credits.sql` и `queries/exports.sql` читают `books`, `chapters` и `runs`. Верная причина: ни один из этих запросов не выбирает `*` и не называет новых колонок, поэтому сгенерированный код не двигается (греп по `*.sql.go` — ноль вхождений). ⇒ **`books` ЛЕЖИТ в мире sqlc**, значит риск NULLABLE денежных колонок наступит на ПЕРВОМ же запросе, который их выберет, — не «никогда», а «пока не спросили». ⚠ Нашла это зона САМА, четвёртым заходом по прямому вопросу владельца «нет ли чего, что ты умолчала»; ни один гейт поймать это не мог — сторожат поведение и форму, а не то, что отчёт о себе ГОВОРИТ (`D39.202` п.9) | платформа | скоро | первый запрос, выбирающий денежные колонки, не роняет генерацию | **D39.208** | +| 305 | ⚠ **`make check` ПЛАТФОРМЫ ПРИ ТАЙМАУТЕ ПАКЕТА ПЕЧАТАЕТ ЗАГОЛОВОК `--- FAILURES ---` И НИЧЕГО ПОД НИМ.** Замер верификатора 06.09: пакет упёрся в дефолтный десятиминутный таймаут (`FAIL … 600.251s`), секция отказов ПУСТА, ни одного `--- FAIL:` — оператор получает «check упал» **без единого имени**. ⇒ «go test вышел ненулём» и «тест упал» — разные события, а прибор их не различает. ⭐ Это платформенное ЗЕРКАЛО урока, ради которого каталог мутаций движка завёл отдельный вердикт `INCONCLUSIVE`: там различение построено, здесь нет. ⚠ Сам прогон, вскрывший это, верификатор объявил **INCONCLUSIVE и в выводы НЕ взял** — он шёл под нагрузкой тринадцати агентов, и приписывать причину «частично настроенное окружение краснит батарею» отказался сам, назвав это той же ошибкой, которую ловит | платформа | скоро | таймаут пакета называет пакет и причину, а не пустую секцию | **D39.207** | +| 306 | ⛔ **СЕМЬСОТ ЯКОРЕЙ БЕЗ ТОКЕНА НЕПРОВЕРЯЕМЫ, И 59% ИЗ НИХ УЖЕ НЕ УКАЗЫВАЮТ ТУДА, КУДА УКАЗЫВАЛИ.** Замер Fable 5 06.09 (выборка 80, seed фиксирован, метод — blame-триаж: коммит последней правки СТРОКИ ДОКА → цель на том коммите → сравнение): цела **31** · уехала **25** · переписана либо исчезла **22** · не судится 2. ⇒ **59% (±11 п.п.)**. ⚠ Линт сверяет по токену 202 и честно печатает «без токена — несверяемы: 780», но ЗАГОЛОВОК «0 проблемных якорей» читается как «всё цело» — прибор отвечает на свой вопрос, а читают его как ответ на другой (`D39.202`). ⚠ **Дрейф сосредоточен там, где он ОЖИДАЕМ:** 34 из 47 сдвинувшихся — в ЗАМОРОЖЕННЫХ отчётах, чьи тела улика по `D23.3` и обязаны описывать дерево НА ДАТУ; их чинить НЕЛЬЗЯ, им нужен штамп HEAD в шапке. **Опасны 13 в ЖИВЫХ носителях**, и часть из них — в ШАПКЕ журнала, то есть в первом, что читает сессия. ⇒ заказ, тремя шагами и без велосипедов: **(1)** заголовок линта печатает ПОКРЫТИЕ («сверено N · несверяемы M · из них с изменившейся целью — K»), чтобы гейт перестал врать формой; **(2)** ОДНОРАЗОВАЯ механическая миграция тем же скриптом: «цела» → дописать токен автоматически, «уехала» с единственным попаданием → пере-навести, «исчезла» → список на руки; замороженным отчётам вместо пере-наводки штамп коммита и исключение из линта; **(3)** правило «токен при касании» остаётся удержанием линии; **(4)** ⛔ **грамматика УЛИКИ — `path:line@`**, которую линт сверяет через `git show :path`, а НЕ против HEAD (~20 строк в `counts.py`). Без неё автор, цитирующий мёртвый указатель как ПРЕДМЕТ записи, вынужден снимать форму якоря руками — я так и сделал 06.09 и объявил это в тексте, но это подгонка ЗАПИСИ под модель прибора, а не починка модели: **законно как последнее исключение, незаконно как привычка**. Та же форма закрывает и ЗАМОРОЖЕННЫЕ отчёты, которым сегодня штамп HEAD стоит прозой (`research/31`/`32`). ⚠ Сегодня без (2) правка любого дока превращается в игру «бей крота»: каждое касание вскрывает соседний голый якорь. ⚠⚠ **ПЕРЕ-ЗАМЕР 06.09 ГРАММАТИКОЙ САМОГО ЛИНТЕРА — МАСШТАБ ОКАЗАЛСЯ В РАЗЫ МЕНЬШЕ, И ЭТО МЕНЯЕТ ЗАКАЗ.** По 117 живым докам: **214 якорей с токеном** (это и есть те, про кого «0 проблемных») и **1776 без токена**; за конец файла целят 66, однозначно разрешаются 9, и семь из девяти — ВНЕШНИЕ цитаты (стандартная библиотека Go, чужой фронтовый код). ⇒ **настоящий внутрирепозиторный протухший якорь ОДИН** (испр. 06.09 автором замера): `docs/architecture/05-decisions-log.md:21`=`Эррата 28.08-и` — **в ШАПКЕ журнала, которую сессия читает первой**; цель нашлась `git log -S` по тексту якоря и пере-навёдена с токеном. ⚠ **Второй кандидат (`PROGRESS.md:71` → `README.md:95`) оказался АРТЕФАКТОМ РАЗРЕШЕНИЯ ИМЕНИ, а не дефектом** — и он же служит уликой к правилу (2) строки 299. ⭐ **Дешёвый метод для ведра «исчезла», исполненный, а не описанный:** `git log -S'<текст якоря>' -- <док> | tail -1` даёт коммит, ВВЕДШИЙ якорь; `git show <коммит>:<цель>` — что стояло в ту минуту ДОСЛОВНО; `git grep` — сегодняшний адрес. Угадывания нет ни на одном шаге. ⛔ **ОПИСАНИЕ ЧУЖОГО МЕТОДА В ЭТОЙ СТРОКЕ БЫЛО ЛОЖНЫМ — СНЯТО 06.09.** Абзац писал, что «59 % на выборке 80» получены наивным резолвингом (голое `mining.go:40` из подкаталога ищут от корня, не находят, объявляют мёртвым). **Наивный резолвинг — метод АГЕНТСКИХ чисел** («42 %», «19 из 32 мертвы»), и опровергнуты им именно они; тем же способом автор пере-замера получил «31 мёртвый из 36» и не понёс их, потому что стал сверять расхождение. Замер Fable 5 устроен иначе и так же описан в ГОЛОВЕ этой строки: берутся только ЗОННО-ПРЕФИКСНЫЕ пути, `git blame` даёт коммит последней правки СТРОКИ ДОКА, `git show <тот коммит>:<цель>` — цель на ту минуту, и сравнивается СОДЕРЖИМОЕ с HEAD. ⇒ строка противоречила сама себе: голова описывала blame-триаж, хвост объявлял его наивным резолвингом. **Класс строки 299, только внутри бэклога.** ⚠ **ДВА ЧИСЛА ОТВЕЧАЮТ НА РАЗНЫЕ ВОПРОСЫ, и потому ни одно не опровергает другое.** Пере-замер грамматикой линтера спрашивает «указывает ли якорь в СУЩЕСТВУЮЩУЮ строку HEAD и совпадает ли токен» — ответ: 214 с токеном, 1776 без, за конец файла 66, однозначно разрешаются 9, настоящий внутрирепозиторный протухший ОДИН. Замер blame спрашивает «изменилось ли СОДЕРЖИМОЕ цели с той минуты, когда строка дока была написана» — ответ: ~59 % на выборке 80. Первый вопрос про HEAD, второй про ДРЕЙФ; строка обязана нести оба, а прежняя редакция вычитала одно из другого. ⚠⚠ **И вопрос HEAD слеп ПО ПОСТРОЕНИЮ к тому самому якорю, ради которого строка заведена:** якорь шапки журнала был написан голым — `seeding.go:143-153`, без слэша, — а `docs/scripts/counts.py:595`=`"~" in rel or "/" not in rel` относит такую форму к «неразбираемым» и пропускает МОЛЧА, ДО всякой проверки файла. ⚠ **Испр. 06.09 по ревью Fable 5: файл НЕ переименовывали** — `seeding.go` жив и сегодня (128 строк), а `bankmaterialize.go` ДОБАВЛЕН `6ec9f8a` 29.08, и в него ПЕРЕЕХАЛ код. Прежняя редакция этой строки писала «переименовали», и следствие «ветвь «файла нет» не выстрелила» было лишним: голое имя до той ветви не доходит по построению. Прибор не видел ровно того случая, с которого начался заказ, — и «0 проблемных» был честен про свой вопрос и слеп про этот. ⚠ И одно слово в этой строке названо неточно: пере-замер сделан ГРАММАТИКОЙ линта (его правила разрешения путей и целей), но не самим линтом и не сверкой токенов — у голых якорей токенов нет — этот якорь линт не видит по построению, и два абзаца строки описывают РАЗНЫЕ приборы одним словом. ⚠ И у метода есть ложные срабатывания: две находки этого же прохода я проверил руками — одна («`STACK.md:11` исчезло») оказалась ЛОЖНОЙ, цель жива и точна | оркестратор | скоро | линт печатает покрытие; голых якорей в ЖИВЫХ доках нет | **D39.202** | +| 307 | ⛔ **СПАН ПОД ПОДПИСЬЮ «СКОЛЬКО ЗАКАЗАНО» — ЛОЖЬ ЯРЛЫКОМ, И ЧЕСТНАЯ ФОРМА ДРУГАЯ.** Для заказа, выраженного ЗНАКАМИ, `Run.ordered_chapters` несёт не заказанное, а **СПАН** — сколько глав заказ ЗАТРАГИВАЕТ, считая главу затронутой независимо от того, куплена ли она целиком (`pricing.QuoteUnits` ставит `Chapters: max(chapters, 1)`, вызывающий передаёт `chaptersSpanning`, и сам код называет это «coarser of the two figures»). ⚠ **Замер зоны:** заказ на ОДИН юнит из четырёх в первой главе даёт `1` — **сто процентов завышения на самом дешёвом заказе**, то есть на том, которым сервис пробуют впервые. ⇒ число под именем «ordered chapters», превышающее заказанное, — ложь ярлыком, сколь угодно последовательная. ⭐ **Разбор, снявший спор:** нужда, которую зона защищала («видно, докуда дошли деньги»), настоящая, а носитель неверный — «докуда» есть **ПОЗИЦИЯ** («достигает главы N»), а не **КОЛИЧЕСТВО** («2 главы»), и позиция у платформы УЖЕ ЕСТЬ (`Quote.ThroughChapter`, `BookOrder.ThroughUnitID`). ⚠ Спан ≠ позиция для заказа-продолжения: спан считает затронутые от текущей точки, позиция — ординал. ⇒ **честная форма:** `ordered_chapters: null` для символьного заказа (зеркало `delivered_chapters: null` — «заказано не в главах») + аддитивно `ordered_characters` (эхо запроса) + позиция ординалом, если экрану нужно «докуда». Это смена формы (поле становится нуллабельным) ⇒ минор. ⚠ **Цена смены почти пуста и это ЗАМЕРЕНО:** `ordered_chapters` вошёл в канон только `75ae6f0`, до него в файле НОЛЬ вхождений — клиент 0.10.0 поля не видел никогда, а `ceiling_chapters` тот же минор уже отвергает с 400. ⚠ Поведение менять НЕ требуется: политика «заказ выражен в знаках и меряется в них насквозь» верна и остаётся. До лендинга формы канон описывает ДЕФЕКТ с ⛔-пометкой, а не дизайн | бэкенд+платформа | скоро | `ordered_chapters` нуллабелен, размер заказа эхом, позиция отдельно | **D39.208** | +| 308 | **ВИД ПРОГОНА ЗАКОДИРОВАН НУЛ�ём, И ЭТО ЕДИНСТВЕННАЯ ЕГО МЕТКА ВО ВСЕЙ ПЛАТФОРМЕ.** Явного признака ре-прохода у `LiveRun` НЕТ: `Resnapshot` не годится — он ставится и ОБЫЧНОМУ продолжению после правки банка, а валидация `OrderedChapters == 0 && !Resnapshot` читается «ноль допустим только под пере-снапшот», то есть ре-проход ⇒ resnapshot, а не наоборот. ⇒ **вид прогона различается ЗНАЧЕНИЕМ денежного поля**, и держится это на двух вызовах `max(n, 1)` (`pricing.QuoteUnits`, `runs.chaptersSpanning`). ⚠ **Опасность растёт после лендинга формы заказа** (строка 307): снаружи символьный заказ станет `null`, и единственное место, где `max(n,1)` что-то значит, уходит ВНУТРЬ — следующий читатель колонки (отчёт, CLI) напечатает спан под старым словом и не узнает об этом. ⇒ заказ: **явный признак вида** (`RePass`) вместо кодирования вида нулём. ⛔ **Рантайм-пояса `== 0 && OrderedUnits == nil` ставить НЕЛЬЗЯ** — символьный заказ не может записать ноль ни при каких данных, а гейт от несуществующего состояния завтра прочтут как свидетельство, что состояние бывает. Честная защита до рефакторинга — **ПИН инварианта** «символьный заказ на один юнит пишет в колонку 1, никогда 0» (замер у зоны уже есть — сто процентов завышения на самом дешёвом заказе; норма `D39.209` требует превратить замер в пин) плюс одно предложение в комментарий колонки. ⚠ Это рефакторинг в ДЕНЕЖНОМ коде без дефекта сегодня — отдельным паком, не минором формы заказа | платформа | когда-нибудь (после строки 307) | вид прогона читается признаком, а не значением денежного поля | **D39.208** | +| 309 | ⛔ **ГЕЙТ ВЕРСИИ КОНТРАКТА СВЕРЯЕТ ЧИСЛА, А НЕ ФОРМЫ — И ПОТОМУ НЕ ВИДИТ ГЛАВНОГО РАСХОЖДЕНИЯ.** `TestTheAnnouncedContractVersionIsTheOneTheCanonRatified` сверяет константу сборки с `info.version` канона. Пока эти два числа равны, гейт ЗЕЛЁН — **даже если провод и документ описывают РАЗНЫЕ формы**. Замерено 06.09 трижды за сутки: канон 0.11.0 объявлял полосу «in chapters», а сборка слала юниты; обещал `ordered_chapters: 0` для символьного заказа, а приезжал спан 2; перечислял три значения словаря, а движок слал четыре. **Ни одно из трёх гейт не покраснил**, потому что число совпадало. ⇒ заказ: сверять ПОЛЯ схемы с проводом, а не только версию. ⭐ **Дешёвая форма названа Fable 5 и уже наполовину оплачена нормой:** тест платформы пишет РЕАЛЬНЫЕ ответы в `examples/*.json` (по действующему правилу «фикстуры снимать реальным бинарём»), канон несёт их в `examples:`, линт сравнивает — тогда фраза «both report 0» умерла бы о файл примера, а не о верификатора через сутки. Прозу это не ловит, ЗНАЧЕНИЯ — ловит. ⚠ Вторая половина той же нормы — **авторство**: утверждение канона о ЗНАЧЕНИИ пишет ЗОНА из своих пинов и называет пин в сообщении коммита; оркестратор ратифицирует текст, а не сочиняет его. Три сегодняшние лжи в каноне написаны тем, у кого не было прогона | оркестратор+платформа | скоро | поля схемы сверяются с проводом порождёнными примерами | **D39.208** | + +| 310 | ✅ **ИСПОЛНЕНО ЛЕНДИНГОМ 06.09 — акт `D39.213`, `201363b`; замерено, что дефект успел испортить числа приёмки: общий лог дал лишний пакет и СПРЯТАЛ ДВА СКИПА.** ⛔ **БАТАРЕЯ ПРИЁМКИ УМЕЛА ВЫДАТЬ ЛОЖНУЮ ЧИСТУЮ СПРАВКУ О ТОМ, ЧЕГО НИКТО НЕ МЕРИЛ.** `make check` пишет лог в ФИКСИРОВАННЫЙ путь `platform/.check.log` и удаляет его при зелени. Два прогона в одном каталоге — а 06.09 они шли — молча уничтожают улику друг друга: грепу нечего читать, и батарея печатает **«--- every test ran: no host condition was missing ---»** при ПЯТИ скипах. ⚠ **Наблюдено, не выведено** (прогон зоны v16: трижды `grep: .check.log: No such file or directory`, следом чистая справка, `MAKE-EXIT=0`). Код возврата остаётся нулём, потому что статус берётся от `go test` ДО грепов, ⇒ наружу выходит СПРАВКА О НЕИЗМЕРЕННОМ, а это хуже отсутствия справки: она закрывает вопрос, которого никто не задавал. **Девятая форма ложной зелени** (`D39.202`) в самом приборе приёмки. ⇒ заказ: батарея ПАДАЕТ ГРОМКО, если лога нет (либо имя файла уникально на прогон); мутация «снять лог» обязана краснить `gates.TestTheBatteryNamesEveryHostConditionItsTestsRead`, а не проходить. ⚠ Обходной путь на сегодня, применённый обеими сторонами: числа снимать своим `go test ./... -race -count=1 -v` в файл ВНЕ каталога зоны, куда чужой прогон не дотянется. ⭐ Нашла платформенная зона на СЕБЕ и намеренно НЕ чинила в составе дофикса, чтобы не смешивать предметы посреди лендинга | платформа | скоро | лог не найден ⇒ батарея красная, а не «всё прогналось» | **D39.212** | + +| 311 | **ПОПРОГОННЫЙ ЛОГ БАТАРЕИ КОПИТСЯ: КАЖДЫЙ УПАВШИЙ ПРОГОН ОСТАВЛЯЕТ СВОЙ ФАЙЛ НАВСЕГДА.** Прежнее ФИКСИРОВАННОЕ имя само себя ограничивало — сколько бы прогонов ни падало, оставался ОДИН несвежий файл, и следующий его перезаписывал. Починка `D39.213` сняла коллизию вместе с этим свойством: `.check.log.` не убирает никто. ⚠ **Замер:** к утру 06.09 в корне зоны лежали ЧЕТЫРЕ таких файла нулевого размера от прибитых прогонов и стаб-проб (удалены зоной как её мусор). ⛔ **Опасность НЕ в коммите** — `platform/.gitignore:3`=`.check.log*` их держит, проверено. Опасность в том, что через месяц человек не отличит «мусор от прерванных прогонов» от «лога, который рецепт НАРОЧНО сохранил при падении, чтобы его прочли», — а второе законная и нужная функция, и она тонет в первом. ⇒ заказ: перед прогоном убирать логи, чей PID УЖЕ МЁРТВ (`[ -d /proc/$p ] || rm -f`). ⛔ Голый `rm -f .check.log.*` ставить НЕЛЬЗЯ: он снова снесёт улику параллельного прогона — ровно тот дефект, из которого всё и выросло. ⚠ Привязка к `/proc` линуксовая; зона на Linux, но это оговорка, а не мелочь. ⭐ **Названо ЗОНОЙ про собственную починку уже ПОСЛЕ того, как я её принял** — то есть ценой не приёмки, а совести | платформа | когда-нибудь (следующее касание прибора) | мёртвые логи убираются, живые не трогаются | **D39.213** | + +| 312 | ✅ **ИСПОЛНЕНО ЛЕНДИНГОМ 06.09 `e4211d4`** — счётчик `backend/internal/chunk/ingest.go:86-99`=`TOCUnreadable counts tables of contents`, вынесен в ноты рефлексионным сторожем; пин `TestADeclaredTableOfContentsThatCannotBeReadIsCounted`, пять подтестов, три дороги проверены мутацией порознь, а «не заявлено» и «прочли, цели висят» держатся отдельными случаями. ⚠ **Последняя миля НЕ пройдена и названа зоной прямо:** нота идёт в лог ДВИЖКА (`r.Log.Warn`), а платформа читает `events.jsonl` — то есть тревога есть, а увидит ли её человек, не показано (Д-3, открыт). ⛔ **ЗАЯВЛЕННОЕ, НО НЕЧИТАЕМОЕ ОГЛАВЛЕНИЕ ПРОВАЛИВАЛОСЬ МОЛЧА — И ЭТО САМЫЙ ДЕГРАДИРОВАННЫЙ СЛУЧАЙ КЛАССА, КОТОРЫЙ ТОТ ЖЕ ПАК И ЛЕЧИЛ.** Книга ЗАЯВИЛА оглавление (`properties="nav"` в манифесте либо `toc` в spine), движок не смог прочесть или разобрать эти байты — и тихо падает до spine, отдавая `delimited`, то есть продажу ПО ЗНАКАМ, без единого слова о причине. ⚠ **Улики на момент находки** (адреса намеренно БЕЗ якорей: код починен `e4211d4`, и якорь целил бы в строку, которая дефекта больше не показывает): ошибка чтения глоталась в `ingest.go` обеими ветвями — nav и NCX, — провалившийся разбор возвращал метки, а счётчика не было вовсе (греп по `unreadable`/`tocUnread` в `chunk/` давал пусто). ⛔ **`toc_unresolved = 0`, потому что целей НОЛЬ** — прибор снова честно отвечает на свой вопрос, а читается это как «всё разрешилось» (`D39.202`). ⇒ тревога, построенная для класса M-2 («часть целей не разрешилась»), НЕ покрывает случай «оглавления не прочли вообще». ⇒ заказ дешёвый: один счётчик в `Document` («declared table of contents that could not be read»), который рефлексионный сторож сам вынесет в `IngestNotes()`. ⭐ **Названо строителем в письме о вычитке и НЕ починено** — он сам нашёл это, только когда я спросил про сомнения. **Улика к норме: находка, живущая в письме, носителя не имеет и исчезает** — ровно то, что зона платформы сказала про находки без ряда | бэкенд | скоро | заявленное нечитаемое оглавление называет себя, а не тонет в `delimited` | **D39.202** | + +| 313 | ⛔ **КАТАЛОГ МУТАЦИЙ ДОКАЗЫВАЕТ, ЧТО МУТАЦИЯ СУЩЕСТВУЕТ, А НЕ ЧТО ОНА ЛОВИТСЯ.** Из **211** записей каталога регулярно гоняются единицы (в паке структуры глав — 14, целящие в изменённое поведение); остальные проверяются только на ЖИВОСТЬ ЦЕЛИ грепом. ⇒ зелёный каталог говорит «посадка на месте», а читается как «посадка краснит». **Тот же класс, что `D39.214` п.3: доказано одно, сказано про другое.** ⚠ Носителя у этого НЕ БЫЛО ни строкой, ни рядом — проверено грепом по живому бэклогу 06.09 по прямому вопросу оркестратора; ближайшая строка 252 говорит о ДВУХ конкретных выживших посадках 04.09 и о полном прогоне не говорит ничего. ⭐ **Третий за час случай, когда находка жила только в письме** (первые два — находки платформы без рядов и нечитаемое оглавление строки 312): **находка без носителя не находится.** ⇒ заказ: либо каталог гоняется целиком по расписанию, либо его зелень перестаёт называться доказательством ловли — формулировку выбирает зона, но молча оставлять нельзя. ⚠ Назвал СТРОИТЕЛЬ про собственный пак, единственным из пяти своих сомнений, что закрыл бы ДО продажи ⚠ **Цена полного прогона ЗАМЕРЕНА 06.09, и отсрочка обоснована ею, а не удобством:** 126 записей из 211 гоняют `internal/pipeline` по ~3 минуты ⇒ полный прогон **6+ часов**. При этом 197 непрогнанных — УНАСЛЕДОВАННЫЕ, каждая краснела у заводившей смены. ⇒ это стоячая гигиена, а не крит; зона прямо отказалась изображать закрытие шестичасовым прогоном «вдруг что-то протухло» | бэкенд | когда-нибудь | зелень каталога означает пойманную мутацию, а не существующую запись | **D39.214** | + +| 314 | ⛔ **РАЗРЕЗ ПРОВЕРЯЕТСЯ ТОЛЬКО НА НЕИЗМЕННОСТЬ — НА ПРАВИЛЬНОСТЬ ЕГО НЕ ПРОВЕРЯЕТ НИЧТО.** Ни один гейт, тест или замер не отвечает на вопрос «верны ли ЭТИ границы»: гейт сравнивает «до» и «после», оракул сверяет два прибора движка МЕЖДУ СОБОЙ. ⚠ **Инвариант сохранения доказывает СОХРАННОСТЬ и молчит о КОРРЕКТНОСТИ** — он считает разбиение (каждый читаемый документ либо исключён намеренно, либо ровно в одной группе) и сходится ОДИНАКОВО при верной и при неверной группировке, если та ничего не теряет. ⇒ «инвариант сошёлся на трёх живых книгах» доказывает сохранность, а читается как корректность разреза. Что 71 глава для Kristoff — ВЕРНО, не показал никто; показано лишь, что так говорит его `nav`. **Тот же класс, что `D39.214` п.3: доказано одно, сказано про другое.** ⭐ Назвал СТРОИТЕЛЬ про собственный пак, найдя это в своих же утверждениях, а не в чужих. ⚠ **Измеримая часть ЗАМЕРЕНА 06.09 и расхождения не дала:** «совпадает ли отданный разрез с тем, что книга ОБЪЯВЛЯЕТ» — по трём книгам 193 цели оглавления, **все на уровне документа, ни одной внутрь документа** (Kristoff 71 · isekai 88 · fifty_shades 34) ⇒ там, где объявленное можно сверить механически, оно сходится. **Остаётся ровно некруговая часть: верно ли то, что объявляет сам `nav`** — она требует человеческого суждения и не закрывается ни тестом, ни прибором. ⇒ **строка стоит не как задача, а как признанная ГРАНИЦА** | бэкенд | когда-нибудь | есть носитель, отвечающий «верны ли границы», а не только «не изменились ли они» | **D39.214** | +| 315 | ✅ **ЗАКРЫТА ЗАМЕРОМ 06.09 — ПРОШЛА.** Блокер («промтов пары `en-ru` нет») снят БЕЗ нарушения запрета: у пар-конфига есть ручка `prompts_root` (`backend/internal/config/pair.go:33`=`PromptsRoot string`, проверено мной), и корень промтов-заглушек собран ВНЕ репозитория — в дереве не создано ничего, промт-пака пары как не было, так и нет. **Замер зоны, `tmctl manifest`, EXIT 0, $0:** `structure: declared` · 71 глава / 351 юнит / 356 чанков · `manifest_version` НЕ сдвинут · нумерация плотная 1..71 без дыр и дублей, `number: null` — ноль · id глав уникальны · **`title_raw` на проводе 71 из 71**, настоящие · ценовая проекция на всех трёх уровнях, глав без цены ноль. ⭐ **И то, что видно только на живой НЕ-CJK книге: `heading` пуст у ВСЕХ глав** (шаблона для пары нет), **а `title_raw` заполнен** ⇒ единственное, что несёт название главы для этой книги, — поле, которое построил этот пак. Обоснование §2.5 стало замером, а не доводом. ⚠ Числа — зоны, на её стенде; механизм обхода блокера и чистоту дерева проверил я. ⛔ Прежняя формулировка: **МАНИФЕСТНАЯ ПОЛОВИНА EPUB НЕ ПРОХОДИЛА НИ РАЗУ НА ЖИВОЙ КНИГЕ.** `tmctl manifest` на EPUB владельца не идёт — промтов пар `en-ru`/`ja-ru` не существует, и пак структуры глав чинить это не заказывал. ⇒ `title_raw` на проводе, id глав и ЦЕНОВАЯ ПРОЕКЦИЯ для EPUB держатся **исключительно на фикстурах авторства самой зоны**; книги владельца мерены только на уровне ингеста. ⚠ **Первая же платная EPUB-книга пойдёт по пути, который на живой книге не проходил никогда** — и это ДЕНЬГИ, а не удобство. ⭐ Стоит в отчёте зоны §6, но отчёт не трекер: через месяц его никто не откроет — ровно довод, которым эта строка и заведена | бэкенд+полигон | скоро | манифестная половина EPUB пройдена на живой книге хотя бы раз | **D39.214** | +| 316 | **У ЭРРАТ НЕТ РЕЕСТРА, И ЧИТАТЕЛЬ НОТЫ НЕ МОЖЕТ УЗНАТЬ, КАКИЕ ИЗ НИХ К НЕЙ ОТНОСЯТСЯ, НЕ ПРОЧТЯ ВСЕ.** Замер верификатора 06.09: эррат в шапке **53**, из них 06.09-* — **10**; на `D39.212` их три, на `D39.211` две, на `D39.213` две; длина одной — **929–4020 знаков ОДНОЙ строкой**. ⇒ **чтобы прочесть `D39.212` верно, надо прочесть 7912 знаков эррат при теле акта около 5000 — корректирующего текста БОЛЬШЕ, чем корректируемого**, и цепочка уже глубиной два (`06.09-ж` правит `06.09-г`). ⚠ **Дефект НЕ в объёме правок:** след — это ровно то, ради чего смена стоила своих денег, и все сегодняшние нормы выводимы только из него (что заявлено, кем опровергнуто, чем). Дефект в том, что **у нот реестр есть (`docs/architecture/05-decisions-index.md`), а у эррат нет ничего.** ⇒ дешёвая форма, названная верификатором: строка реестра получает колонку «живые эрраты», `counts.py` её сверяет — тот же класс, что восьмой гард итога регистра: **не помнить, а проверять**. ⚠ **Отложено сознательно, а не забыто:** это седьмая правка прибора за смену, а предыдущие шесть трижды потребовали починки после приёмки; менять гейт на исходе смены — ровно та спешка, которой этот бэклог посвящён | оркестратор | скоро | к ноте один хоп даёт список живых эррат, и его сверяет гейт | **D39.202** | + +| 317 | **У ЧИСЛА, СТОЯЩЕГО В КАНОНЕ, НЕТ ПРИБОРА В РЕПОЗИТОРИИ.** `D39.214` п.6 цитирует замер «сканер по 193 свойствам схем канона, три правила, семь флагов, пять ложных, два настоящих». **Сканер не закоммичен** — проверено грепом 06.09. ⇒ ни «193», ни «семь» не воспроизводимы никем, включая автора. ⛔ **ПОДОЗРЕНИЕ НА НЕПОЛНОТУ СКАНА СНЯТО 06.09 — И СНЯЛ ЕГО ТОТ, КТО ПРИНЁС.** Сначала агент верификатора пере-выполнил три правила по описанию и получил **двенадцать** флагов; это читалось как «зона что-то не досмотрела». Верификатор довёл зацепку до замера сам: **189 свойств, 9 уникальных флагов** — ровно зонные ПЯТЬ ложных плюс `Chapter.number` (настоящая находка, уже диспозиционированная) плюс три `EventStatus.*_reason`, **которые оказались дефектом ЕГО реализации**: правило читало `description` самого поля и не читало РОДИТЕЛЬСКИЙ объект, документирующий все три разом (`docs/architecture/14-api-contract/openapi.yaml:3123`=`unless its own status`). ⇒ **знание там не расщеплено, а централизовано — сказано один раз на три поля, и это лучше, чем трижды.** Семёрка зоны ВЕРНА, пропущенного нет. ⚠ И `OrderOptions.structure` прибор больше не флагует — потому что зона его починила. ⇒ **дефект этой строки — НЕВОСПРОИЗВОДИМОСТЬ числа, а не его неверность**, и срочность соответствующая. ⭐ **Та же форма, что норма «число называет ДЕРЕВО и ПОПУЛЯЦИЮ», только про ИНСТРУМЕНТ:** одноразовый скрипт, давший число в канон, обязан ехать в репозиторий вместе с числом — иначе замер неотличим от утверждения. ⇒ заказ: либо сканер ложится в `platform/` (или `docs/scripts/`) и число пере-снимается им, либо число в каноне помечается как невоспроизводимое. ⚠ Принёс верификатор ПОСЛЕ своего «ок», прямо сказав «это зацепка, а не находка, и опровержением зоны я это не считаю» | платформа+оркестратор | когда-нибудь | число в каноне пере-снимается прибором, лежащим в дереве | **D39.214** | + +| 318 | ⛔ **ПОСТЧЕК БАНКА ОБЕЩАЕТ ЛОВИТЬ СТРАХ ВЛАДЕЛЬЦА И МОЛЧИТ РОВНО ТОГДА, КОГДА ТОТ СБЫВАЕТСЯ.** Комментарий `backend/internal/membank/mempostcheck.go:14-16`=`we injected the wrong dst and the model obeyed it` объявляет, что промах ловит ОБЕ беды — «модель проигнорировала глоссарий» И «мы вложили неверный dst, и модель его исполнила (страх владельца)». Код делает обратное: `present := dstFormPresent(...)`, затем `if present { continue }` — **исполненная неверная строка ПРИСУТСТВУЕТ в выводе, значит промах не пишется**. ⇒ чем послушнее модель исполнила ложь, тем надёжнее прибор молчит; метрика «нет постчек-миссов» означает «банк ИСПОЛНЕН», а читается как «исполнен ВЕРНО». ⚠ Независимое подтверждение в дереве: `docs/experiments/18-editor-wire-probe.md` — «Механизма, который это ловит, в пайплайне нет». ⚠ **Вред реплицирован ДВАЖДЫ на разных проводах и моделях** (`research/24`, транслятор-провод, принято `D39.102`; `experiments/18`, редакторский, принято `D39.108`): неверная строка принята 6/6 и вытеснила верную 5/6. ⇒ немедленно и дёшево — **привести комментарий к тому, что код делает** (правка комментария в хеш не входит); отдельно и дороже — недостающий ДЕТЕКТОР правильности значения. ⛔ Ослаблять `D39.104` НЕ предлагается: закон банка ратифицирован, и доказательств против него нет | бэкенд | скоро | комментарий описывает поведение, и есть носитель у вопроса «верно ли значение» | **D39.202** | +| 319 | ⛔ **ПРИБОР СЛЕПОГО ЧТЕНИЯ ШТРАФУЕТ РОВНО ТО ПОВЕДЕНИЕ, КОТОРОЕ САМ ЖЕ ЗАКАЗЫВАЕТ.** Судимой руке предписано `eval/dovodka/prereg-4axes/stand/editor-p9.md:5`=`Сверяй смысл черновика с исходным текстом` — то есть ОТХОДИТЬ от черновика там, где он искажает оригинал. А блокирующая линза `eval/dovodka/blind-read/PREREG-2-BLIND-READ.md:62`=`точность относительно черновика` меряет верность ЧЕРНОВИКУ, ⇒ мы велим редактору ОТХОДИТЬ от черновика там, где тот переврал оригинал, и меряем его ВЕРНОСТЬЮ черновику. ⛔ **ПРОТИВОРЕЧИЕ КОНСТРУКЦИИ ДОКАЗАНО — ВЕЛИЧИНА ИСКАЖЕНИЯ НЕ ЗАМЕРЕНА, и это разные вещи.** Прежняя редакция строки писала «прибор СИСТЕМАТИЧЕСКИ поощряет якорение» и «отход от черновика записан в ДЕФЕКТЫ»: **испр. 06.09 автором строки** — фраза «Отход от черновика» встречается в сыром судейском массиве ОДИН раз, то есть это наблюдение, а не свойство, и масштаб я выдал за факт, не посчитав. Доказано ровно одно: две бумаги в одном дереве требуют взаимоисключающего. ⇒ вывод замера **ненадёжен ПО ПОСТРОЕНИЮ** независимо от частоты, и величину надо мерить ДО любого следующего решения о тире редактора. ⚠ Задет приоритет владельца №2 («отсутствие выдумок — редактор, сверка с ИСХОДНИКОМ», `D39.198` п.2). ⭐ **Этого довода в отчётах Кодекса НЕТ — он найден консилиумом**, и он сильнее всего, что там написано. ⚠ Обвязка с исходником уже существует в том же дереве (`eval/dovodka/judge-prompts/`), то есть нужен не новый прибор, а ПЕРЕ-ПОДКЛЮЧЕНИЕ готового. ⚠ ⚠ **Три эрраты в носителях замера — ФОРМОЙ БАННЕРА, тела НЕ править** (оба документа заморожены, и пре-рег ценен именно неизменяемостью), и **горизонт у них другой: ПЕРВЫМ касанием полигона, ДО пака починки линзы** — иначе три дешёвые правки будут ждать дорогого пака. Не исполнены ни одна: «правильный ответ по построению — ничья» противоречит собственному тексту отчёта; из §8 пре-рега выпало унаследованное ограничение «опора судьи — черновик, не оригинал»; правило решения готово выдать вывод, который отчёт результата запрещает дословно | полигон | скоро | линза меряет то, что руке заказано, и носители замера не противоречат себе | **D39.198** | +| 320 | **ДВА СОВЕТА ДВИЖКА, КОТОРЫХ ДВИЖОК НЕ ИСПОЛНЯЕТ.** (а) `backend/internal/membank/memseed.go` советует оператору «mark one status: auto», а гард полисемии статус НЕ СМОТРИТ вовсе — условие `a.Src != b.Src || a.Dst == b.Dst || !windowsOverlap(...)`, и совет в пределах одного файла не сработает НИКОГДА. Одна строка плюс тест. (б) `internal/lang/data/``injection.txt` несёт заголовок «НЕПОДТВЕРЖДЁННЫЕ РАБОЧИЕ ВАРИАНТЫ», живой в сборке (`internal/lang/embedded.go:449`), тогда как `membank/memory.go` прямым текстом объявляет «NO ⟨проверить⟩ MARKER, and no fork by status at all» по `D39.104` п.2. ⚠ Правка ДАННЫХ — стоп-мир (`EmbeddedVersion` → `cutTag` → `manifest_key`), поэтому прицепом к паку строки 161, а не отдельным заходом; правка комментария (а) дешева и сегодня | бэкенд | скоро | совет и заголовок описывают то, что сборка делает | **D39.202** | + +| 321 | ⛔ **РЕДАКТОР ПОДБИРАЕТ БАНК БЕЗ ПАМЯТИ О ПРЕДЫДУЩИХ ЕДИНИЦАХ, И ОПРАВДАНИЕ В КОДЕ ЛОЖНО.** Черновая волна передаёт sticky-контекст, редакторская — `nil`; комментарий рядом оправдывает это тем, что единица есть глава либо её часть, «так что внутриглавное окно липкости неприменимо». **Оправдание неверно:** глава РЕГУЛЯРНО делится на несколько правочных единиц (`assignEditUnits` жадно пакует чанки до потолка и закрывает единицу ВНУТРИ главы), а sticky сбрасывается только на границе ГЛАВЫ. ⚠ **ЗАМЕР 06.09 (Fable 5, `tmctl manifest` на `22e079e`, $0):** слайс 25 глав — 57 чанков / 37 единиц / **11 многоединичных глав**; ПОЛНАЯ книга — 2283 главы / 5071 чанк / 4276 единиц / **1962 многоединичных, то есть 86 %**. Прежнее «56 чанков» взято из архивной СИМУЛЯЦИИ, факт 57. ⛔ **И картина «черновик сохраняет — редактор теряет» верна только для СИДОВОГО банка:** на нынешнем стенде все строки mined, базовый банк ПУСТ, черновая волна банка не несёт вовсе, а редакторская — единственная с банком — не переносит между единицами. ⚠ **Экспозиция замерена, дрейф — НЕТ:** теряется 49 банковых строк на 12 единицах, из них у **4** форма перевода уже стоит в черновике (все Confirmed); инцидентов не наблюдено ни одного. ⇒ **сначала мерить на следующем платном прогоне** ($0 по хранилищу), потом строить. ⚠ Теста, фиксирующего нынешний `nil`, НЕТ ⇒ правка это багфикс, а не смена заказанного поведения. ⚠ **Sticky — это множество id БАНКОВЫХ строк, не пересказ повествования**; отчёт Кодекса описал его неверно, и это отдельно опровергнуто. ⇒ предмет: либо передавать, либо привести комментарий к правде — но молча оставлять оправдание, которое разошлось с кодом, нельзя | бэкенд | скоро | редакторская волна либо несёт перенос, либо объясняет отказ верно | **D39.215** | +| 322 | ⛔ **УКАЗАТЕЛЯ ПРИНЯТОЙ РЕДАКЦИИ НЕТ: НЕУДАЧНАЯ ПОВТОРНАЯ РЕДАКТУРА ЗАТИРАЕТ ДОСТУПНЫЙ РЕЗУЛЬТАТ.** ⛔ **ПРОДУКТОВАЯ РАМКА ЭТОЙ СТРОКИ БЫЛА НЕВЕРНА И СНЯТА 06.09 (поправка владельца):** функции «заказать вторую редактуру» у нас НЕТ. Есть **ре-проход**, законный только при СДВИНУВШЕМСЯ банке — человек исправил термин и просит пере-прогнать книгу. ⇒ верное утверждение узкое: **ре-проход пере-делывает затронутую единицу ЦЕЛИКОМ** тем же редакторским промптом (режима «правь только термин» в движке нет), **прежний текст остаётся в чекпойнтах, но без адреса** — ни одна строка статуса на него не указывает, экспорт его не видит, отката нет; **и ничто нигде не сравнивает старый вывод с новым**. ⛔ **Единственный БЕЗВОЗВРАТНЫЙ путь найден:** ре-проход флагнулся → оператор делает `redrive` → сброс стадий сносит чекпойнты **ФЛАГНУТОЙ стадии по всем снапшотам**, и прежний хороший чекпойнт РЕДАКТУРЫ в их числе. ⚠ **Испр. 06.09: стояло «ВСЕ чекпойнты чанка» — шире правды**, черновая строка уцелевает (`backend/internal/pipeline/volume.go:717`=`deletes only the FLAGGED and SKIPPED`). Довод о безвозвратности от этого не страдает: теряется именно принятая редактура. ⚠ Попутно: комментарий `backend/internal/store/chunkstatus.go:52-57` про «резюм переписывает строку» ЛОЖЕН — обычный резюм её не пишет. ⭐ Это ЯДРО гипотезы 1 отчёта `research/32`, и консилиум его ПОДТВЕРДИЛ — единственная его архитектурная часть, устоявшая целиком. ⚠ Полный revision-контур (схема, семантика `chunk_status`, экспорт, контракт, платформа) — смена курса и дизайн-пак масштаба строки 161, НЕ заказ этой строки. **Заказ здесь узкий: указатель принятой редакции**, чтобы повторная попытка не могла уничтожить принятое | бэкенд+платформа | скоро | вторая редактура не может отнять первую | **D39.215** | +| 323 | **ЧЕСТНАЯ ЦЕНА ПРАВКИ БАНКА — НЕ «ПЕРЕПОКУПКА КНИГИ», И ЭТО МЕНЯЕТ ДОВОД, КОТОРЫМ ЗАЩИЩАЛИ БЕЗДЕЙСТВИЕ.** ⛔ **ФОРМУЛА ПЕРЕПИСАНА 06.09 ПО ЗАМЕРУ — прежняя редакция была завышена в ТРЁХ местах.** Верно: подпись через `bank-apply` двигает ТОЛЬКО редакторскую волну и стоит **единицы, чей исходник содержит ключ термина внутри его окна** (плюс те, где термин перестал инжектироваться); остальное ре-пиньтся за $0 **при явном `--resnapshot`**. Правка СИДОВОГО файла двигает обе волны и добавляет черновые чанки с ключом плюс **до двух следующих чанков той же главы** (рябь переноса), а также все единицы с перекупленным черновиком — **последнего смета НЕ ВИДИТ**. ⛔⛔ **И главный денежный член был пропущен: проход терминолога перекупается НА КАЖДУЮ ПОДПИСЬ, он тратится ДАЖЕ БЕЗ `--resnapshot`, и его ПЕРЕПОКУПКА невидима смете и согласию** (⚠ испр. 06.09: стояло «невидим смете» без оговорки — шире правды: смета ПЕРВОГО прогона проход несёт потолком, `backend/internal/pipeline/priceprojection.go:317`=`BookOnceUSD: r.bookOnceUSD()`; невидима именно перепокупка на подписи, строка 38) (центы: $0.005 на четырёх главах, $0.026+$0.034 на десяти; потолок — бюджет). ⚠ Прежнее «опровергнуто кодом и тестом» тоже сильнее правды: пин доказывает игрушечный случай — две главы по чанку, mined-only, без прохода майнинга, без ряби и каскада. ⚠ Значение: «оставить как есть, потому что чинить дорого» — довод, которым закрывали вопрос неверной банковой строки, — **отпадает по цене**. Сам закон банка при этом НЕ оспаривается: доказательств против `D39.104` нет ни у одного голоса. ⚠ Оговорки названы и не спрятаны: бесплатность неполная, проход терминолога пере-покупается (строка 38), и всё это только при ЯВНОМ `--resnapshot` | оркестратор | скоро | цена правки банка названа формулой, а не страшилкой | **D39.215** | +| 324 | **ВХОД РЕНДЕРА ЗАКРЫТ: СОСЕДНЕЕ ПОВЕСТВОВАНИЕ НЕЛЬЗЯ ПОДАТЬ ДАЖЕ ПРАВКОЙ ПРОМПТА.** Шаблон принимает фиксированный набор плейсхолдеров, неизвестный `{{…}}` — жёсткая ошибка. ⇒ на дежурный ревью-вопрос «заработает ли это без правки Go» ответ здесь сегодня **«нет»**, и это признанный долг, а не дефект: пара-данные общности так и задуманы, но ИМЕННО этот вход расширяется только кодом. ⛔ **ИСПР. 06.09: сцепка со строкой 321 была МИМО ПРЕДМЕТА** — там переносятся id банковых строк по инъекционному каналу, а не через шаблон, и в шаблон это не упирается вовсе. В шаблон упирается только «дать редактору соседний ТЕКСТ», и это отдельная гипотеза. ⚠ И это НЕ долг общности: набор — движковые рантайм-значения, пар-специфики в нём нет; таблица в данных стала бы вторым носителем. ⇒ **строить не надо**, предмет переформулирован в контракт входа. Если гипотеза соседнего текста подтвердится замером — правка Go снапшот НЕ двигает, но использование в боевом промпте двигает его через хеш промпта ⇒ редакторская волна перекупается ОДИН раз | бэкенд | когда-нибудь | вход рендера расширяем данными либо отказ объявлен в носителе | **D39.215** | + +| 325 | ⛔ **«МЫ ПРОСТО НЕ БУДЕМ ВПУСКАТЬ EPUB И НЕ-CJK» — СЕГОДНЯ НАМЕРЕНИЕ, А НЕ ФАКТ: ИНТЕЙК ИХ ПРИНИМАЕТ.** Замер 06.09: приём и обработка имени `.epub` закреплены тестом платформы (`platform/internal/books/books_test.go`, кейсы с расширением), то есть сужение входа до того, что умеет ВЫДАЧА, — это **код, а не решение**. ⚠ Значение прямое: строка 283 держит «структура глав для выдачи гейтит бету для не-CJK и EPUB», и её компенсация на бете («просто не впускаем») не работает, пока отказа нет в коде. ⇒ либо интейк отказывает форматам, чью выдачу мы не умеем, с честной причиной пользователю, либо 283 обязана быть сделана ДО впуска. ⭐ Найдено разбором границы беты 06.09; предмет — компенсация, объявленная и не построенная | платформа | скоро | вход физически сужен до того, что умеет выдача, либо выдача умеет впускаемое | **D39.215** | +| 326 | ⛔ **ПОНЯТИЯ «БЛОКЕР БЕТЫ» В ТРЕКЕРЕ НЕТ, И КРИТЕРИЯ ВПУСКА ПЕРВОГО ПОЛЬЗОВАТЕЛЯ В РЕПОЗИТОРИИ НЕ СУЩЕСТВУЕТ.** Замер 06.09: гейт печатает «блокеров очереди: 0», но этот вес — про ОЧЕРЕДЬ, а не про бету; слово «бета» в строках бэклога встречается считаное число раз и НИ РАЗУ не как критерий впуска (⚠ счёт из строки снят 06.09: я привёл «три из 236», а пере-счёт даёт 5 из 229 — оба числа были неверны, а утверждение в них не нуждается); греп по `docs/`, `platform/docs/`, `backend/docs/` на «первый пользователь / первая внешняя книга / впуск» не даёт ничего. ⇒ **вопрос «сколько ещё до беты» не читается из трекера не потому, что мало сделано, а потому что трекер никогда не нёс этого понятия.** ⚠ Практическое следствие: любой ответ о сроке беты сегодня — оценка сессии, а не состояние проекта, и проверить его нечем. ⇒ заказ: **линия остановки как ПРОВЕРЯЕМОЕ условие** (прогон на чужом файле через ту же дверь · деньги сходятся либо маржа видна пользователю · застрявший прогон видно и лечится · ни один экран не врёт о единице · вход сужен до того, что умеет выдача) — формулировку утверждает ВЛАДЕЛЕЦ, носитель заводит оркестратор | владелец → оркестратор | скоро | в дереве есть проверяемый критерий впуска первого внешнего пользователя | **D39.215** | + +| 327 | ⛔ **ОСТАТОК ПОЛИГОН-ПАКЕТА №4 ЖИВЁТ ТРИ МЕСЯЦА ВНУТРИ ПРОМТА, И В НЁМ ЛЕЖИТ ДАТИРОВАННЫЙ РИСК.** ⚠⚠ **Срочное: замерный судья `memory_eval.py` работает на `gemini-2.5-flash`, у серии объявлен shutdown **16.10.2026** — около шести недель от 06.09.** Носителя у этого НЕ БЫЛО: единственное вхождение слага в бэклоге — проза про ЦЕНЫ другой модели, а не про миграцию нашего судьи (проверено грепом по предмету, не по имени). ⇒ после отключения замерный контур встанет, и узнаем мы это отказом, а не планом. Там же: двойной `extra_body` и отсутствие 404-ретрая при живом слаге. ⚠ Остальные пять пунктов остатка, тоже без носителей: матчер content-filter подстрокой + самотест · параметризация языка/жанра судейского промпта (ja/en сняты под zh-рамкой) · проба судьи-дублёра 18+ · калибровка echo-gate (`D25.7`) · minimal-pairs 100–150 для shadow fidelity (`D25.2`). ⭐ **Класс, а не случай:** промт `POLYGON_PACKAGE4_SESSION_PROMPT.md` с 12.07 стоит «частично отработан, residual ЖИВ», как отдельная сессия НЕ запускался — то есть **носителем работы служит промт, а не трекер**, и в трекере этой работы не видно вовсе. ⇒ заказ: остаток становится строками, промт уходит в архив с баннером исхода, а в ролевой промт оркестратора вносится правило выхода «residual → строка бэклога, промт в архив» — сегодня его там нет, и именно поэтому пакет №4 жив три месяца | полигон | скоро (миграция судьи — ДО 16.10) | остаток несут строки, промт в архиве, правило выхода записано | **D39.216** | +| 328 | ⛔ **ЗОННЫЕ СЕКЦИИ «БЭКЕНД»/«ПОЛИГОН» ЖИВУТ В ФАЙЛЕ ЗОНЫ ОРКЕСТРАТОРА — ОСТАТОК ЛОВУШКИ, КОТОРУЮ ВЫНОС БЭКЛОГА ЗАКРЫЛ НАПОЛОВИНУ.** Замер 06.09 (классификация 250 коммитов `docs/PROGRESS.md` с 25.08 по секциям): голова 167 · таблица 148 · зонные секции 66; «только бэклог» 48 ⇒ вынос таблицы снял 32 % случаев, с бюллетенем 58 %, остаток 42 % — проза шапки и зонные секции. Сами секции — 297 409 байт (41 % файла до выноса). У фронта и платформы зонные журналы СВОИ по решению владельца (`frontend/docs/frontend-PROGRESS.md`, `platform/docs/platform-PROGRESS.md`), у бэкенда и полигона — нет, и потому их отчёты едут в файл, который коммитит оркестратор. ⇒ вопрос владельцу: заводить ли зонные журналы бэкенду и полигону по тому же прецеденту. ⚠ Цена бездействия не гипотетическая: ловушка «коммит своей строки уносит чужой отчёт» срабатывала трижды за смену 05.09 | владелец | скоро | решение владельца о зонных журналах бэкенда и полигона (перенос — отдельным лендингом) | **D39.218** | diff --git a/docs/PLATFORM_MONEY_TRUTH_SESSION_PROMPT.md b/docs/PLATFORM_MONEY_TRUTH_SESSION_PROMPT.md index 734a43b8..eb2afa68 100644 --- a/docs/PLATFORM_MONEY_TRUTH_SESSION_PROMPT.md +++ b/docs/PLATFORM_MONEY_TRUTH_SESSION_PROMPT.md @@ -38,7 +38,7 @@ ⚠ Ссылка на этот файл обязана быть в каждом платформенном промте; из семи прежних сослались пять, и норма дважды проскользнула. Здесь она стоит. 3. `platform/docs/DEFECT_REGISTER.md` — ряды `PD-441`, `PD-424`, `PD-438`. -4. Строки **282**, **325**, **326** бэклога (`docs/PROGRESS.md`, греп `^| N |`). +4. Строки **282**, **325**, **326** бэклога (`docs/BACKLOG.md`, греп `^| N |`). 5. `platform/README.md` + зонный журнал (шапка, не целиком — он 5029 строк, см. §4.0). **Ратифицированное — в теле промта:** diff --git a/docs/POLYGON_INSTRUMENT_REPAIR_SESSION_PROMPT.md b/docs/POLYGON_INSTRUMENT_REPAIR_SESSION_PROMPT.md index ca10bd50..6a7a6de9 100644 --- a/docs/POLYGON_INSTRUMENT_REPAIR_SESSION_PROMPT.md +++ b/docs/POLYGON_INSTRUMENT_REPAIR_SESSION_PROMPT.md @@ -29,7 +29,7 @@ ## 3. Карта чтения — ЗАКОН 1. `CLAUDE.md` — цели и гардрейлы. -2. Строка **319** бэклога (`docs/PROGRESS.md`, греп `^| 319 |`) — предмет целиком. +2. Строка **319** бэклога (`docs/BACKLOG.md`, греп `^| 319 |`) — предмет целиком. 3. `eval/dovodka/blind-read/PREREG-2-BLIND-READ.md` — §5 (линзы) и §8. 4. `eval/dovodka/prereg-4axes/stand/editor-p9.md` — инструкция судимой роли. 5. Строки **300**, **265**, **143** бэклога. diff --git a/docs/PROGRESS.md b/docs/PROGRESS.md index 4de82c88..2099d8c9 100644 --- a/docs/PROGRESS.md +++ b/docs/PROGRESS.md @@ -1,6 +1,6 @@ # Журнал прогресса -> **⟶ ТЕКУЩЕЕ СОСТОЯНИЕ** (на 2026-09-06, голова D39.217 — КУРС: движок и платформа до «работает и отдаёт результат», фронт ЗАМОРОЖЕН и P7 его НЕ размораживает (D39.147). **ОЧЕРЕДЬ №22** (единственный носитель — здесь; роль передана 01.09, №21 закрыт нотой передачи D39.184). ⚠ **ЗАКАЗ ВЛАДЕЛЬЦА 01.09 — ПЕРВЫМ:** (0а) **ревизия документации на ПРОТУХШЕЕ** — по всем зонам, не только тронутым; (0б) **планы доработок в БЭКЕНД и ПЛАТФОРМУ** по остатку бэклога и регистра; (0в) **вынос неактуального в АРХИВ** (`docs/archive/`, `platform/docs/archive/`) — за сутки 31.08 закрыто много, и часть носителей стала историей. ⚠ Трезвость по масштабу (пере-считано 02.09): **90** живых дока в `docs/` (пере-счёт 04.09: `find docs -name '*.md' -not -path 'docs/archive/*' | wc -l`), 8 в `platform/docs`, 9 в `backend/docs` — ⚠ из 94 ВРЕМЕННЫЙ остался ОДИН (`DOC_CLEANUP_PLAN`, живой до закрытия батчей Б14/Б15/Б17); два прежних временных уехали в `archive/reports/` 02.09; счёт бэклога — бюллетенем ниже, открытых рядов регистра платформы — 106 (major 3), всего рядов 458 (пере-счёт `python3 docs/scripts/counts.py`; с 04.09 оба числа под гардом `--check`, прежние 95/3 разошлись молча) ⚠ (ревизией 02.09 ряды **154** и **157** переведены из «скоро» в «когда-нибудь»: их гейтом стоял первый холодный прогон, он ОТРАБОТАЛ 31.08 и оба предусловия оказались другими — разбор в самих ячейках, ни одна НЕ закрыта). ⚠ Числа доков `counts.py` НЕ сторожит — при переносе файлов пере-считывать руками командой `find docs -name '*.md' -not -path 'docs/archive/*' | wc -l`. ⚠ И предупреждение о МЕТОДЕ, купленное сменой №21: «выглядит протухшим» ≠ «протухло». Три факта оркестратора опровергнуты ЗАМЕРОМ сессий, а якоря `15-money-path.md` в девяти случаях из двенадцати РОДИЛИСЬ верными и сгнили дрейфом — то есть ревизия обязана быть исполнением, а не чтением. ⚠ **ОЧЕРЕДЬ, унаследованная от №21** (три лендинга 31.08 — секция «СОСТОЯНИЕ ПАКОВ» ниже): **(1) ~~РАЗРЫВ ЦИКЛА~~ ЗАМКНУТ ЖИВЬЁМ 04.09** — пользователь получил EPUB настоящего ПЛАТНОГО перевода ЧЕРЕЗ API, `epubcheck` 5.3.0 на СКАЧАННОМ файле 0/0/0/0 (книга `bk_SS5VES2JELESJSTR`, потрачено $0.278319 из гранта $0.60 при потолке пака $1.5, санкция D39.189). Дверь выдачи построена и проверена исполнением: `202`+`Location`, поллинг с `Retry-After`, Range 206 · второй клиент 200 · аноним 401 · чужая книга 404, TTL с GC, идемпотентность третьего создающего вызова. Все ТРИ сценария строки 216 предъявлены живьём (подпись банка · halt на потолке с exit 4 · `409 run_not_resumable/ceiling_reached` и лечение новым прогоном). +> **⟶ ТЕКУЩЕЕ СОСТОЯНИЕ** (на 2026-09-06, голова D39.218 — КУРС: движок и платформа до «работает и отдаёт результат», фронт ЗАМОРОЖЕН и P7 его НЕ размораживает (D39.147). **ОЧЕРЕДЬ №23** (единственный носитель — здесь; роль передана 06.09, №22 закрыт нотой передачи D39.217; ⚠ испр. 06.09: коммит передачи `c992ee5` бампнул голову и НЕ тронул номер — гейта на номер очереди нет вовсе, `counts.py` сверяет только голову, поэтому носитель разошёлся молча). ⚠ **ЗАКАЗ ВЛАДЕЛЬЦА 01.09 — ПЕРВЫМ:** (0а) **ревизия документации на ПРОТУХШЕЕ** — по всем зонам, не только тронутым; (0б) **планы доработок в БЭКЕНД и ПЛАТФОРМУ** по остатку бэклога и регистра; (0в) **вынос неактуального в АРХИВ** (`docs/archive/`, `platform/docs/archive/`) — за сутки 31.08 закрыто много, и часть носителей стала историей. ⚠ Трезвость по масштабу (пере-считано 02.09): **90** живых дока в `docs/` (пере-счёт 04.09: `find docs -name '*.md' -not -path 'docs/archive/*' | wc -l`), 8 в `platform/docs`, 9 в `backend/docs` — ⚠ из 94 ВРЕМЕННЫЙ остался ОДИН (`DOC_CLEANUP_PLAN`, живой до закрытия батчей Б14/Б15/Б17); два прежних временных уехали в `archive/reports/` 02.09; счёт бэклога — бюллетенем ниже, открытых рядов регистра платформы — 106 (major 3), всего рядов 458 (пере-счёт `python3 docs/scripts/counts.py`; с 04.09 оба числа под гардом `--check`, прежние 95/3 разошлись молча) ⚠ (ревизией 02.09 ряды **154** и **157** переведены из «скоро» в «когда-нибудь»: их гейтом стоял первый холодный прогон, он ОТРАБОТАЛ 31.08 и оба предусловия оказались другими — разбор в самих ячейках, ни одна НЕ закрыта). ⚠ Числа доков `counts.py` НЕ сторожит — при переносе файлов пере-считывать руками командой `find docs -name '*.md' -not -path 'docs/archive/*' | wc -l`. ⚠ И предупреждение о МЕТОДЕ, купленное сменой №21: «выглядит протухшим» ≠ «протухло». Три факта оркестратора опровергнуты ЗАМЕРОМ сессий, а якоря `15-money-path.md` в девяти случаях из двенадцати РОДИЛИСЬ верными и сгнили дрейфом — то есть ревизия обязана быть исполнением, а не чтением. ⚠ **ОЧЕРЕДЬ, унаследованная от №21** (три лендинга 31.08 — секция «СОСТОЯНИЕ ПАКОВ» ниже): **(1) ~~РАЗРЫВ ЦИКЛА~~ ЗАМКНУТ ЖИВЬЁМ 04.09** — пользователь получил EPUB настоящего ПЛАТНОГО перевода ЧЕРЕЗ API, `epubcheck` 5.3.0 на СКАЧАННОМ файле 0/0/0/0 (книга `bk_SS5VES2JELESJSTR`, потрачено $0.278319 из гранта $0.60 при потолке пака $1.5, санкция D39.189). Дверь выдачи построена и проверена исполнением: `202`+`Location`, поллинг с `Retry-After`, Range 206 · второй клиент 200 · аноним 401 · чужая книга 404, TTL с GC, идемпотентность третьего создающего вызова. Все ТРИ сценария строки 216 предъявлены живьём (подпись банка · halt на потолке с exit 4 · `409 run_not_resumable/ceiling_reached` и лечение новым прогоном). > ⛔ **ЧЕТЫРЕ ПОТОКА РАБОТЫ И ИХ ЗАВИСИМОСТИ (заведено 06.09; до этого жило только в переписке с владельцем).** > **(1) ПОЛИГОН — «ремонт прибора»** (`docs/POLYGON_INSTRUMENT_REPAIR_SESSION_PROMPT.md`, строки 319 · 300 · 265 · 143): > блокирующая линза слепого чтения меряет верность ЧЕРНОВИКУ, а судимой руке предписано отходить от него по исходнику @@ -37,7 +37,7 @@ > - **Курс:** этапы ОБЩНОСТЬ · КАЧЕСТВО БАНКА · ПАКЕТ-ЧЕКЕРОВ · ФРОНТ-ЭРА · шов/платформа/движковые блокеры — ПРОЙДЕНЫ (D39.59–123). Хвосты курса живут строками: 16 (полная цена холодного старта; edit-волна на малых прогонах отработала и оплачена — 58 вызовов волновым драйвером 23–25.07 плюс 648 до драйвера, счёт по леджерам `~/books/gu-zhenren/**/*.db`) · coldrun-b фаза C заморожена чекпойнтом легитимно (D39.86; эталон денег/поведения — coldrun-a, read-only); развилка 0731 решена и исполнена (D39.87/91, код `553f1a3`). > - **Горизонт (D39.62/67, освежён D39.95):** **ДОБОР ИДЕАЛА** (первым прогоном: оси голоса 24 · авто-режим · цена 16; остаток арбитража банка = рецензент спорных кластеров при ре-пробе — D39.102). ⚠ **Испр. 05.09 (D39.198 п.5):** прежняя редакция держала здесь ТРИ предусловия, снятых владельцем, — жильцы ролей (149: разморозка ничего не разблокирует, пока идут доработки) · веса K1–K12 (13а: веса не нужны, мерить по узлам) · вне-претрейн чекпоинт (55: прогоняем на тех же текстах, оговорка — ограничение ВЫВОДА, а не требование новой книги) → ВТОРАЯ ПАРА живьём (ja→ru; преп 81) → МАСШТАБ → пилот Ф2.5 (гейт резюме-строки 80; строки 62–68, 85) → Ф3 ридер-IDE (69–71). **Стоячие:** ToS-триггер 25.10 · Ш-2 до go1.27 (⚠ + x/text Unicode 17 тем же тулчейном — строка 119, реестр §Б-108 справочника якорей) · платные прогоны разблокированы (проба провода — D39.97, конфиги 112 залендены). > - **Стек (полная карта роль→модель→конфиг→квирки — [STACK.md](STACK.md), D39.126):** draft deepseek-v4-flash thinking-ON `low` **⚠0731** → терминолог (та же модель) → editor deepseek-v4-pro БИЛИНГВ ИНТЕРИМ (топология ПОДТВЕРЖДЕНА при неразличимости жильцов — D39.117; закон-блок ОБЯЗАТЕЛЕН и ВНЕСЁН — D39.104 п.2, вайр-батч принят D39.199; glm-5 резерв; вахта маппинга эффорта pro — §Б-108) → судья gemini (Ф2, в движке НЕ построен — строка 33); канал B Mistral+grok; ~$0.85/ранобэ (D30.4) — ⚠ **ТРИГГЕР ПЕРЕ-КАЛИБРОВКИ СРАБОТАЛ 31.08** (испр. 02.09): платный прогон отработал и дал собственную оценку движка `projected_book_usd = 1.1377277707` на десяти главах при куплённых $0.436110; число D30.4 держать как июльское. ⚠ **Вендор-факты 13–15.08 (пере-пин ИСПОЛНЕН и ПРИНЯТ, D39.137):** таблица цен запинена ПИКОМ (flash 0.44/1.32 · pro 1.32/3.96/кэш-хит 0.044 за 1M; счёт шиппинг-c1 = 100% DeepSeek ⇒ ×4.2–4.4 в пике / ×2.1–2.2 в долине — замер по трём прогонам); ⚠ **испр. 05.09: носители про эффорт `pro` БОЛЬШЕ НЕ ПРОТИВОРЕЧАТ** — и квирки (§3г), и `STACK.md` говорят одно: ручка ДОХОДИТ до модели с вендор-апдейта 13.08. Живой остаток один — вендор-сверка маппинга и ВЕЛИЧИНА эффекта, строка **237**(б); ⚠ ВЕСА pro сменились под тем же слагом (V4-Pro-0813, класс D39.61) — вахта-риг готов (остаток 172); покупки фазы Д на deepseek до 16.08 16:00 UTC — по старым ценам. ⚠ **ВЕСЬ банковый контур (банкнота+терминолог+классификатор) ВКЛЮЧЁН в shipping-c1 с `b8154cd`** — `enabled: true` у обоих гейтов и `classify_types: true`, бюджеты по $1.00 (прежде жил только ран-локальным конфигом книги; строка 140 — ⛔ его единственный вход `mining.contrast_path` в git ОТСУТСТВУЕТ, развёртывание обязано положить артефакт, иначе контур не исполняется вовсе, носитель — строка 251; сверка STACK.md 09.08 — факт шире прежней декларации «одна банкнота»); эскалация в shipping за `budget_usd: 0` (STACK.md §примечания). -> - **ЕДИНЫЙ БЭКЛОГ — секция «Бэклог» ниже** (одна таблица, единственный трекер; каждая петля обязана иметь диспозицию: решено / отложено-с-записью / отклонено; ведёт оркестратор). **СЧЁТ ОЧЕРЕДИ на 05.09 (скриптом по таблице — `python3 docs/scripts/counts.py`; обновлять при каждом лендинге):** всего **239** строк · зона бэкенд **113** строго / **158** широко (⚠ колонки счётчик читает С КОНЦА — испр. D39.116) · **блокеров очереди 0** (236 закрыта D39.175), платные прогоны разблокированы · «скоро» **105** (перечень — грепом по таблице, рукописный список снят D39.126) · гейт-строка эксп-22: 153 (плюс 150 — руки владельца; ⚠ 55 из гейтов СНЯТА — D39.198 п.5); строка 5 — остаток гейчен ре-пробой 74, носитель события теперь строка 188 (аудит D39.140); остальное «когда-нибудь». ⚠ Счёт — НИЖНЯЯ граница долга, не потолок (разбор — легенда таблицы ниже). +> - **ЕДИНЫЙ БЭКЛОГ — отдельный файл [BACKLOG.md](BACKLOG.md)** (одна таблица, единственный трекер проекта, ID строк прежние; каждая петля обязана иметь диспозицию: решено / отложено-с-записью / отклонено; ведёт оркестратор). ⚠ **Счёт очереди — бюллетень в ШАПКЕ ТОГО ФАЙЛА, здесь копии НЕТ** (`python3 docs/scripts/counts.py`; переезд 06.09 — D39.218). > - Архивы хроники: `archive/PROGRESS-2026-07-04-10.md` (D31) · `-10-13` (D39.6-гигиена) · `-13-25` (стройка паков 11–16, rerun2) · **`-25-31` (паки 17–20 · мини-прогон · полигон-пакеты 5–8 · ToS · холодный прогон; D39.26–58)** · **`-08-01-02` (сессии №9/№10: общность · качество банка · coldrun-b · открытие фронта/платформы; D39.59–90, срез D39.105)** · **`-08-02-04` (сессии №11–№13: ручки эффорта · стандарты · контракт API · платформа P0 · банк-арбитраж; D39.91–105 + снимок шапки эры №15)** · `-08-04-09` (пинги закрытых паков эры №15) · **`-08-14-15` (закрытые бэкенд-записи №16–17: эмиттер шва · migrate · пере-пин DeepSeek; вынесено D39.139)**. Записи ниже — живой хвост (№16+, эра D39.124+; подрезка D39.139). ## 📌 СОСТОЯНИЕ ПАКОВ @@ -138,274 +138,9 @@ оба ложны с `adf5e53`/`58bca19`; висячая ссылка на закрытую 246 в шапке секции «Бэкенд»; корень `backend/docs` в линтере. -## Бэклог (ЕДИНЫЙ, собран 26.07, актуализация 04.08 D39.99/D39.101; правки — только через оркестратора) +## Бэклог -Закрытые строки здесь НЕ хранятся — они уходят в D-лог с номером решения. **ID строки стабилен навсегда** (не перенумеровывается и не переиспользуется — на «строку N» ссылаются доки и промты, D39.80). Вес: «блокер-очереди» = мешает текущему шагу · «скоро» = ближайшие 1–2 касания · «когда-нибудь» = записано, не потеряно. Длинная строка начинается жирным лидом — таблица сканируется по лидам; «диспозиция сверху, археология вниз», ячейка >800 байт — кандидат на выселение в `architecture/13-tech-debt-anchors.md` (D39.125 п.3/D39.126). ⚠ **Счёт очереди — НИЖНЯЯ граница долга, а не потолок:** трекер содержит только замеченное, и 02.08 дважды за $0 свежие глаза вытащили из кода дефекты, которых в нём не было (релей фронта → строки 99/100/102; приёмочное ревью → третий шов в 104 и честность в 105); ленту ✅ шапки читать как «долга нет» неверно (D39.89). **Зонные бэклоги (решение владельца 02.08, D39.84):** фронт и платформа ведут СВОИ бэклоги (`frontend/docs/BACKLOG.md` · `platform/BACKLOG.md`) — их строки сюда НЕ заходят; здесь движок/полигон/доки, включая движковые стыки фронта (зона «бэкенд», как 99–102); строки 96/97 переехали в платформенный (П-1/П-2), надгробия-указатели сохранены. - -| ID | Хвост (одной фразой) | Зона | Вес | Чем закрывается | Источник | -|---|---|---|---|---|---| -| **— ВИСИТ НА ВЛАДЕЛЬЦЕ —** | | | | | | -| 2 | Четыре вопроса границы «алгоритмического идеала» (Annotator · семантический судья · ja→ru §B5 · ru-target до/после) | владелец | скоро (гейт «добора идеала» перед МАСШТАБОМ) | отдельное решение | D39.33, D39.38 | -| 4 | **Ре-чек ToS по триггерам** — первый ИСПОЛНЕН 31.07, дельт вердиктов нет (D39.57); предмет Google-мониторинга перевешен на цепочку договора (PUP · Additional ToS · Google APIs ToS); следующие: квартал 25.10.2026 · первая лейблованная книга · любая правка `accepts_labels` | владелец/полигон | скоро (следующий триггер 25.10.2026) | отдельное решение (правило) | D39.32, D39.57 | -| 5 | **Арбитраж банка: замер ИСПОЛНЕН и ПРИНЯТ (research/24, D39.102).** Закрыто классом: равноправный совет · кросс-модельные веса уверенности · self-consistency · селекция из вариантов · отказ-сигнал ⟦TM-NO-DST⟧; Q2 отвечен — семейства не окупаются (C3−SC=+3 и все три добычи = один кластер; glm-соло 25/45 > совет 23/45). **ОСТАТОК СТРОКИ:** рецензент-другого-семейства ТОЛЬКО на спорных КЛАСТЕРАХ (слот при ре-пробе 74), роутинг целыми family/series-юнитами (G4), эмиссия рецензента — та же draft/⟨проверить⟩. История захода — D39.89/90/101/102 | полигон/ресёрч | **ОСТАТОК ГЕЙЧЕН ре-пробой 74** (D39.102 п.2) | замер (остаток) → решение | D39.89, **D39.102** | -| 6 | **Строка Gemini в `accepts_labels`** — ждёт слова владельца о подписи интерпретации сужения как разрешения; ре-чек 31.07 понизил приоритет: подпись даёт ПРАВО, но не судью 18+ (фильтр неконфигурируем D22.6 + обход запрещён договором) — возвращаться при вопросе, требующем именно права | владелец | когда-нибудь | отдельное решение | D39.32, D39.57 | -| 7 | Q2 «редактор под `sexually-explicit`» (grok-4.3 интерим · glm-5 после сверки ToS Z.AI · mistral вон) | владелец | когда-нибудь (перед первой explicit-книгой) | отдельное решение | D39.27 п.7 | -| 8 | D22.7 пер-чанковый L3-скрин — несня­тое предусловие первой erotica-книги в проде, отдельный гейт | владелец | когда-нибудь | отдельное решение | D22.7, CURRENT-STATE (оркестратор) | -| 9 | Промпт-слой под лейблом: лейбл не доезжает до промпта — должны ли переводчик/редактор знать о свойстве контента | владелец | когда-нибудь | отдельное решение | CURRENT-STATE (владелец, из пака-17) | -| 10 | Дата создания аккаунта OpenAI (низкий приоритет, OpenAI вне цепочки) + применимость OpenAI Sharing & publication policy 2022 (quirks:128) | владелец | когда-нибудь | отдельное решение | D39.32 | -| 11 | Флип coverage-гейта (`enabled:false`, D12-Q4) — за подписью владельца ; при флипе решить судьбу v1.1 quote-absorption (D12-Q1, Python-first лок-степ) | владелец | когда-нибудь | отдельное решение | D39.34(2) | -| 12 | **`postcheck_gate` в hard-gate** — требует пере-замера recall (recall чекеров измерен и низок); ⚠ «fn=0» демоции #10 класс-вакуумен на labels (ноль одно-Han-позитивов, D39.78) — пере-замер обязан добрать одно-Han-позитивы, на «fn=0» не опираться; одно-Han-класс при gate-on вне гейта (Unverified+Demoted); тем же решением строится HARD-value-детектор 成/万 (Q3 §6 — честный hard-gate требует value-чека; либо раньше при ненулевом потоке value-дефектов добора, D39.79; **$0-прототип получен эксп-21: `battery.check_numbers`, симметричный разбор, синтетика 16/16 — D39.117**) · recall существующих гейтов печатал арм C эксп-21 на контаминированном срезе (D39.108/D39.117) | владелец | скоро (⚠ испр. 05.09: `D39.205` п.4 сделал эту строку ПРЕДУСЛОВИЕМ решения владельца по гейту глоссария — прежний вес «когда-нибудь» противоречил ратифицированному; порядок работ — строка 295) (после фазы 2) | отдельное решение | D39.34(2), D24.4+D28.1, D39.39, D39.78, D39.79 | -| 13 | **Включение платной петли ремонта + per-class исходы ремонта** (схемное решение принимается вместе) — вернуться при расширении классов детекторов и ненулевом остатке; ⚠ при включении: репэйр-гард №5 после #10 слеп на одно-Han-дифференциал (демоция в обоих прогонах ⇒ 0>0 — репэйр, стёрший верно отрендеренный одно-Han-термин, не ветируется; D39.78-ревью) | владелец | когда-нибудь | отдельное решение | D39.38, D39.39(а), D39.78, CURRENT-STATE | -| 13б | **`speech-cue.txt` zh НЕ шипить до замера голос-флаггера; замера НЕТ (D39.86) — оси не считались НИ РАЗУ.** ⚠ **Причина ПЕРЕ-НАЗВАНА: прежний довод «редакторская волна не гонялась» ПРОТУХ 31.08** (холодный прогон `coldrun-v16` её гонял и оплатил — строка 16); живой блокер — ПУСТОЙ РЕЕСТР профилей, см. ниже. ⚠ **ГЕЙТ ПЕРЕ-СНЯТ 05.09:** прежний требовал «подписанных профилей (строка 24)», а подпись владелец снял (D39.198 п.5) — значит гейтом остаётся ОДНО: первый прогон добора идеала С редакторской волной. ⛔ **Но снятие подписи открыло дыру, и её надо закрыть раньше стройки:** реестр `voices:`/`addresses:` физически заполняет только подпись (`backend/internal/config/seed.go`, греп `no miner emits them`), и если подписи нет — заполняет НИКТО. Вопрос вынесен строкой 24. ⚠ Сам гейт в схеме ЕСТЬ (`internal/config/pipeline.go` `VoiceGate`, пак-19/D39.55). ⚠ `rules=` в отчёте = «гейт СКОНФИГУРИРОВАН», не «отработал» — до фикса читать по знаменателям `replies=` — носитель **292** (испр. 05.09: 105 закрыта D39.200 только половиной (а), знаменатели уехали в 292). Археология дословно — `architecture/13-tech-debt-anchors.md` §Б-13б. ⚠ **ПОПРАВКА 23.08 (№19):** заполнить `voices:`/`addresses:` может только подпись владельца (`internal/seed/seed.go:23`=`Voices and Addresses are the two D21 record types` — «no miner emits them»), а при пустом реестре `RunVoiceChecks` выходит на `!reg.HasData()` ДО ВСЕХ осей, поэтому нулями отдаются и оси, и знаменатели — «ноль флагов» неотличим от «оси не считались». ⚠ Отдельно: `gates.voice` отсутствует в `backend/configs/`, НО в конфигах реальных прогонов (вне git) он ВКЛЮЧЁН — `~/books/gu-zhenren/coldrun-a/pipeline.yaml:68` и `coldrun-b:71`, `enabled: true`; дыра не «оператор забыл включить», а «шаблоны репозитория гейт не несут» | владелец | отложено-до-замера | первый прогон добора идеала С РЕДАКТОРСКОЙ ВОЛНОЙ (оси голоса, строка 24) → отдельное решение | D39.56, PACK19_BUILD §7.2, чат 31.07, D39.86 | -| 14 | **Четыре data-инженерных флага фазы-2 общности, каждый с рекомендованным дизайном** (§5 отчёта): ё-фолд → target-данные (`char_fold`; смена сигнатуры core-примитива через вердикт-несущий банк, сдвиг `memory_version`) · segmentation-фолбэк громким (ломает контракт corridor-фолбэка `pipeline.go:839-848` + голден-фикстура на нём; лечение — объявить блок в голден-yaml) · `Fertility` per-script map (калибровка ждёт боевого токенизатора) · `source-encoding.txt` + Go-реестр декодеров | владелец | когда-нибудь (следующий пак общности) | отдельное решение | D39.64, GENERALITY_PHASE2 §5.1–5.4 | -| 86 | **Мелкие открытые решения одним списком** (свип D39.66): echo-семантика дропнутого c-lite-члена (D39.18 — оставить pre-c-lite?) · magnitude-кап тяжёлой CJK-утечки (D38.3 п.4в; сейчас strip+flag) | владелец | когда-нибудь | отдельные решения | D39.66, D39.69(feed_cap закрыт §1) | -| **— ХВОСТЫ ХОЛОДНОГО ПРОГОНА (исполнен достаточно, D39.58; Р7 владельца) —** | | | | | | -| 16 | **Полная цена холодного старта — ЖИВОЙ ОСТАТОК ОДИН: цена ДОВЕДЁННОЙ ДО КОНЦА книги не измерена.** Холодный прогон `coldrun-v16` 31.08 отдал 3 юнита из 14 и остановлен снапшот-гардом. ⚠ **Довод «редакторская волна не гонялась» ПРОТУХ 31.08** (испр. 02.09): она гонялась и оплачена — 4 чекпойнта `edit/editor/deepseek-v4-pro` на $0.214865; не мерена именно ПОЛНАЯ цепь одним заходом до конца книги. **Числа ДО редактуры — база прогона `~/books/gu-zhenren/coldrun-b/reprobe/bank-low/guzhenren-bank-low.db`** (10 глав, `low` на черновике И на бэнк-ролях; арифметика снята 23.08 №19): вся ДРАФТ-стадия $0.031639 (flash $0.021289 + pro $0.010350) · терминолог $0.005750 · классификатор $0.007706 · **весь заход $0.045095**, слагаемые дают именно его. ⚠ Числа в ИЮЛЬСКИХ деньгах — множитель пере-пина DeepSeek 4.47 (D39.179 п.1), сегодня тот же заход $0.2017. ⚠ Фаза C `coldrun-b` закрыта владельцем как неуспешная (02.08, D39.90), её деньги не тронуты ($0). Строка держит и оси голоса (13б/24) | бэкенд | когда-нибудь (гейт: первый ЗАВЕРШЁННЫЙ прогон) | добор идеала | D39.58, **D39.90** | -| 18 | **Эмиссия головы 蛊**: сид-половина = чек-лист (определяющий терм книги сидится `allow_short`, D39.50); эмиссия-КАНАЛ демотирован до ИЗМЕР-ГЕЙТА (Q7): полигон-замер «меняет ли эмиссия головы рендер композитов» — строить ТОЛЬКО по эффекту и ПОСЛЕ #10 (однознаковый пост-чек чинится чекер-паком); перед стройкой резолвить K-гейт и KWIC-грязь одиночной головы | полигон → бэкенд | скоро (санкция Q7 D39.70 — после #10, очередью с ре-пробой) | полигон-замер → решение | D39.58, D39.60, D39.69 | -| 24 | ⚠ **ГЕЙТОМ БОЛЬШЕ НЕ ЯВЛЯЕТСЯ — испр. 05.09 (D39.198 п.5):** прежняя редакция держала «профили голоса НЕ ПОДПИСАНЫ» как предусловие, а владелец подписи снял («зачем мне это подписывать») и вытаскивать черновик из книжного дерева не надо. Голос — приоритет №3 из трёх, то есть работа, а не блокер. **Остаток: авто-режим флага** (проект Б не гонялся) · оси голоса A–D · слот инъекции голоса и решение gates.voice при ненулевых осях (D39.55/D21 п.2) · слой-2 voice не строим до доказательства слоя-1 · сверить until_ch 白凝冰 при курации сида (D19.3в). ⚠ **ОТКРЫТЫЙ ВОПРОС, РОЖДЁННЫЙ СНЯТИЕМ ПОДПИСИ:** реестр профилей (`voices:`/`addresses:` сида) сегодня физически заполняет ТОЛЬКО подпись владельца — `backend/internal/config/seed.go`, греп `no miner emits them`. Если подписи нет, ЗАПОЛНЯЕТ КТО? Ответ нужен раньше стройки: без него строка 13б навсегда «отложено до замера» | бэкенд | когда-нибудь | работа третьего приоритета | D39.40, D39.58 | -| **— ТЕКУЩАЯ ОЧЕРЕДЬ (D39.59) —** | | | | | | -| 78 | **Леджер денег = НИЖНЯЯ граница**: «2xx body decode failed (call IS billed)» — провайдер списал, исходная попытка в `request_log` НЕ попадает (≤$0.009/сессия); дизайн фикса ГОТОВ (GENERALITY_PHASE2 §5.6: `BilledDecodeFails` + per-billed-attempt settle с `Estimated=true`), но это money/ledger-путь — не $0-хастл. **Живое число (D39.86):** на ре-пробе 74 — 3 таких вызова на 14, неизвестность **$0.015111** при леджере $0.114378 (13% захода); движок засеттлил оценку и честно напечатал `estimated-cost rows: 3` ⇒ канал ВИДЕН, но `decode_error` при этом ещё и терминален (не retryable, не escalatable) — 3 из 7 терминальных флагов пробы A | бэкенд | когда-нибудь (money-паком) | отдельное решение (дизайн §5.6) | D39.61, D39.64, D39.86 | -| 79 | **Граница ПЛОТНОСТИ письма для серий**: `enabled` через Go-константу `cjkScriptNames` — новый плотный скрипт требует правки Go (head-finality уже в данных script-series.txt; пре-существующая граница, D39.75). Первые два компонента строки (isCyrLetter→`isTargetWordLetter` · magnitude `SourceScripts`-гейт) исполнены пакетом-чекеров, D39.78 | бэкенд | когда-нибудь | следующий пак общности / касание чекеров | D39.64, D39.78 | -| 90 | **Ф2-кандидаты 02-mvp-плана без носителя** (свип-хвост, D39.73): CometKiwi/T-index метрики судьи · Batch API судьи (экономия) · llama-server-интеграция локали · стриминг — взять/закрыть при пилот-препе; + H16 самоулучшение (V3-п.2, ПТ-26): дизайн петли по данным судьи — тем же препом | полигон/бэкенд | когда-нибудь (Ф2.5) | пилот-преп-промт (с 85) | 02-mvp-plan, D39.66, D39.73, D39.80 | -| **— НАХОДКИ СВИПА ПОЛНОТЫ (D39.66: 951 обязательство проверено, потери возвращены в трекер) —** | | | | | | -| 80 | **Резюме-слой памяти** — проза-суммарайзер ЗАКРЫТ (D39.69); строка = ГЕЙТ ПИЛОТА Ф2.5: первый деливерабл пилота — «допускает ли автономная нарратив-состояние-строка ДЕТЕРМИНИРОВАННЫЙ верификатор (source-anchored) — или это D1-компаундинг со схемой»; не-покрытые классы (source-anchored reveal · арк-колбэки без ключа) реальны, но не измерены как дефект | Ф2.5 (Q3 подтверждён D39.70) | когда-нибудь (пилот) | Ф2.5 пре-рег | D25 п.8–9, D39.66, D39.69 | -| 81 | **ja-преп B6-ja (сужено пост-сверкой D39.66)**: Поливанов-валидатор (`translit_policy` = «Phase 2»-заглушка, `backend/internal/store/migrate.go:187`=`translit_policy TEXT` и `backend/internal/store/migrate.go:195`=`ruby_reading`) + kana-омограф POS/known-word гейтинг / B6-токенизатор (`backend/internal/membank/memory.go:1181`=`KANA and HAN are deliberately NOT boundary-checked`); чек-лист kana-алиасов сида УЖЕ построен (backend/README §ja + `AttachRubyAliasesToManual`) — остаток в нём только дизамбигуация двойных чтений (тот же B6) | бэкенд | когда-нибудь (перед ja→ru) | ja→ru-пак (рядом 35) | D16.4, D17.1, D18, D39.66 | -| 82 | **Морфо-гейт РОДА** (C3: русский глагол прош. вр. при gender=hidden = механический спойлер-канал; «жалоба №1 читателей MTL»; python-сайдкар/pymorphy, связка с морфопроходом Decl из 73). **$0-прототип получен эксп-21** (`battery.check_gender`: карточки из подписанного сида, фильтр по именительному падежу, 86–112 сверок/арм — D39.117); движковый гейт не построен | бэкенд | когда-нибудь (Ф2-гейты) | отдельный пак (с 52) | 06-реестр C3, research/12, D39.66, **D39.117** | -| 85 | **Пилот-преп добор** (к переупаковке PACKAGE4): Bertalign GOLD-пары + zh→ru spot-check (D29.2в; GPL-тулинг отдельно) · fidelity-каскад R2 shadow с корпус-подготовкой (D25.2) · exp08 v3 пере-съём COGS до фиксации budget_usd (D21.8) | полигон | когда-нибудь (Ф2.5) | пилот-преп-промт | D25, D29, D21.8, D39.66 | -| **— ПАК-21 «чекеры»: РАСТВОРЁН (D39.62); шестёрка исполнена 2/6 фазой 2 (D39.64: #11 · строка 26), остаток — ниже —** | | | | | | -| 93 | **Остатки строки 93 после пачки (D39.82):** строгий OffLanguage (36а, deferred D39.78) · 分之-разметка прежде стройки DC2 word↔word (полигон) · F4-хвост: `redrive --dry-run` обходит pre-flight, а `store.Open` мутирует SPOF-файл (миграции + recoverReservations; коммент «mutates nothing» неверен) — pre-flight и на dry-run при существующей БД либо read-only план; заодно stat-скип точной формой `fs.ErrNotExist`; **обострение приёмкой D39.134:** на устаревшей БД `--dry-run` выполняет ПОЛНУЮ миграцию схемы БЕЗ restore point (write-open без шва migrate) — воспроизведено исполнением. ⚠ **Остаток НЕ однороден по гейту (сверка 02.08):** F4-хвост и строгий OffLanguage свободны, а `分之`-часть ГЕЙЧЕНА полигон-разметкой среза («строить вслепую против мандата» — якорь техдолга) ⇒ не подавать строку как «малое касание без гейта» | бэкенд/полигон | когда-нибудь | малое касание / полигон-слот | D39.78, D39.82 | -| 98 | **DC7 грейд-консистентность — пере-гейчен по сид-покрытию (D39.82):** замер пачки реален (25 юнитов/93 «разряд» ≠ канон «класс» на labels-финалах), НО финалы — прогоны до/вне сид-v2-канона, а грейды 甲/乙/丙/丁等 теперь approved-записи сида с decl-формами: mempostcheck флагнёт «разряд» промахом dst; строить DC7 только если ОСТАТОК девиаций переживёт сид-покрытие — замер на первом СИДОВОМ прогоне добора идеала; дом канона при стройке = book.yaml (как register_blocklist; ратифицировано D39.82 — НЕ dc-checkers.txt, посылка D39.79 исправлена) | бэкенд | когда-нибудь (гейт: первый сидовый прогон добора идеала) | замер остатка → решение | D39.79, D39.82, SMALLPACK §5-E1 | -| 28 | Банк-линт латиницы в dst или строгая форма языкового предиката (7 строк утечки алфавита проходят экран); сюда же хвост закрытой 128 (D39.102: NoDst-почти-сентинел, латиница-target — дословно не переехал при закрытии, восстановлен аудитом D39.140) | бэкенд | когда-нибудь (добор идеала — носитель «свежий мини-прогон» растворён D39.67, актуализация D39.79) | касание чекеров при данных добора (помнить оговорку 36а: «甲等 → класс Цзя» строгой формой не ловится) | D39.52, D39.62, D39.64, D39.79 | -| 28а | **Prompt-injection-проба входного текста** ($0): сепаратор ⟦TM-BANK-v1⟧ и якорь-подобные маркеры В ТЕКСТЕ КНИГИ — поведение среза/парсера/инъекции (книга = недоверенные данные; инструментов у моделей нет, но канал банкноты читает вывод по маркеру) | бэкенд/полигон | когда-нибудь | малая проба | сводка-ревью 26.07 | -| **— СВИП ГИПОТЕЗ —** | | | | | | -| 30а | **Перерисовка puml-диаграмм под пост-пак-20 пайплайн** (терминолог, банкнота отдельным файлом); дом диаграмм теперь `backend/docs/` — правятся одним коммитом с кодом (D39.80); PUML НЕ рендерить (гардрейл); ловушки activity-синтаксиса, стоившие реального бага 25.07, — `12-go-style-notes` §1 (дом на онбординг-пути бэкенда; строка держит указатель, а не сам факт — носитель с запланированной смертью для долговечного факта не годится) | бэкенд | когда-нибудь | ближайший пак, касающийся pipeline | аудит доков 26.07, D39.80 | -| **— ОТДЕЛЬНЫЕ ПАКИ/РЕШЕНИЯ (бэкенд, добор идеала) —** | | | | | | -| 31 | Слой-2: извлечение дискурс-норм/few-shot из ТЕЛ промтов (форсинг = ja→ru) | бэкенд | когда-нибудь | отдельный пак (идеал D39.33) | CURRENT-STATE, D39.33 | -| 33 | **native-Gemini судья** (Ф2-механизм) ; до прод-заводки: $0.01-проба thinking⊆max_tokens на боевом слаге (D22.3) + включить sanitizer в pipeline-c2 при оживлении (D33.4б) | бэкенд | когда-нибудь | отдельный пак (идеал) | CURRENT-STATE, D39.33 | -| 34 | **Генеральность нарезки** — ОСТАТОК после фазы 2: сами per-script коэффициенты (`est_out` ja завышен ~1.7× МОЛЧА · `EstimateTokens` недосчитывает кириллицу); консолидация класса письма СДЕЛАНА (один дом `DenseScript`, D39.64) — лечение = `Fertility`-map (строка 14) + офлайн-калибровка при боевом токенизаторе | бэкенд | когда-нибудь | строка 14 + отдельный пак (с ja→ru) | D39.37(5), D39.64 | -| 34а | **Экран кодировки не видит `` без XML-объявления** (епаб с gb18030-метой прочтётся как UTF-8) — до-паковая дыра, сознательно не тронута пачкой 14а (паритет со старым ридером) | бэкенд | когда-нибудь | отдельное решение | D39.54, SMALLPACK §8 | -| 35 | **Не-CJK майнер/банк**: en-детектора не существует (hanRuns=0), ja с zh-таблицами активно неверен (0/10); нужен второй ДЕТЕКТОР (прототип `mine_nonhan.py`) + G1–G10 требования generic-майнера (вкл. квадратичность G9 ≈4.6 ч) | бэкенд | когда-нибудь | отдельный пак generic-майнера (с ja→ru) | D39.37(8), D39.43, D39.50 п.8, POLYGON_PREMEASURE §6 | -| 36 | Кластеризация майнера глотает родовые титулы (族长/学堂家老 в кластере 葛家) — закрыто на границе сборки входа, сама кластеризация не чинилась | бэкенд | когда-нибудь | отдельное решение | D39.43, D39.45 | -| 36б | **Второе мнение по банку**: рецензент ДРУГОЙ моделью, несогласия — отдельной колонкой подписной таблицы (судья-с-декоем в роли рецензента; решает владелец, D39.46-ограничение не бьёт). ⚠ **Бэкенд-стройки НЕТ** (D39.69 закрыл по нужности); замер ИСПОЛНЕН (research/24, D39.102) — остаток = строка 5: рецензент спорных КЛАСТЕРОВ при ре-пробе 74, роутинг family/series-юнитами; переживёт замер → тонкая колонка наблюдаемости, не гейт | полигон (замер) → бэкенд (только если переживёт) | когда-нибудь (слот при ре-пробе 74, остаток строки 5) | замер остатка → решение | D39.69, D39.90, **D39.102** | -| 36г | **Проводной формат каналов пересказан прозой в каждом пар-промпте, парсер в Go, связи нет** — формат в шаблон движка (`{{banknote_format}}`); линты держат класс, дублирование остаётся | бэкенд | когда-нибудь (со следующей правкой промптов) | отдельное решение (Р5) | D39.58 | -| 37 | **Квадратичности: `AttachKWIC`** (16.8 с / 2000 кандидатов; фикс — многошаблонный поиск; ⚠ опция фикс-пака 128 НЕ взята — «чисто не ложится»: автомат в `membank` неэкспортирован, вынос в общий пакет = рефакторинг слоя, `terminology` PURE не может импортировать банк-стор — отчёт пака §4 п.5, D39.118) + src-правило банкноты при промахе чанк-пути (строка × длина книги; на 10 главах не видна) | бэкенд | когда-нибудь | отдельное решение | D39.45, PACK20_BANK_BUILD §8.5.1, D39.58, D39.118 | -| 38 | Смета не видит пере-покупку прохода терминолога на каждой итерации подписи (роль не пишет `chunk_status`, не видна `projectRebill`) · хвост приёмки №13: адрес чекпойнта батча = ординал при частотной сортировке ⇒ реюз чекпойнтов прохода ~0 на инкрементальной книге — **механика ПОДТВЕРЖДЕНА КОДОМ фикс-паком (§2 отчёта, D39.118):** G1 двигает состав юнитов и те же ординалы, на первом прогоне после пака перекупаются все бэнк-батчи (центы) | бэкенд | когда-нибудь | отдельное решение | D39.45, PACK20_BANK_BUILD §8.5.2, D39.102, D39.118 | -| 39 | S12 частичен: `malformedSeparatorAt` не ловит подмену слова разделителя и обрыв токена (комментарий обещает) | бэкенд | когда-нибудь | отдельное решение | D39.45, PACK20_BANK_BUILD §8.5.3 | -| 40 | `bankTokenBudget`: worst-case зашит zh→ru (признанная утечка §0; CJK-цель недобирает вдвое) | бэкенд | когда-нибудь | отдельное решение | D39.45, PACK20_BANK_BUILD §8.5.4 | -| 41 | golden: вторая фикстура С langpack (сейчас пинится только фолбэк-путь) ; + golden-счётчики голоса (хвост D39.58) ⚠ **ПРЕДМЕТ ШИРЕ ЗАЯВЛЕННОГО, испр. 05.09 по итогу веера.** Снято у прежней формулировки: «не пинится ничем» — ЛОЖНО, zh с настоящими langpacks гоняется в пяти интеграционных тестах; дыра именно в ПОБАЙТОВОМ пине. И «побочно это фикстура общности» — вывернуто: нынешний golden И ЕСТЬ доказательство цели №2 (пара БЕЗ пакета проходит книгу end-to-end байт-в-байт), вторая фикстура служит целям детерминизма и денег. **Настоящая цена дыры:** один из фолдов снапшота — руками поддерживаемая строка `RenderFormatVersion` (`backend/internal/membank/memory.go`); забыли бампнуть при смене байтов провода — денежная ось молчит, а контент-ось перекупает затронутые чанки БЕЗ гарда и БЕЗ согласия (`rebill.go`: «the CONTENT axis … re-bills exactly the touched chunks and is invisible here»). Единственный механический подстраховщик здесь — побайтовый golden, которого на langpack-пути нет. | бэкенд | когда-нибудь | отдельное решение | D39.37(6) | -| 42 | `prompt_override` — легальный обход гарантии слоя-2, сформулировать честно | бэкенд | когда-нибудь | отдельное решение | D39.37(7) | -| 43 | `request_log` без скоупа/ретеншена + `first_flag_reason` = третье представление истории попыток (корень — неразведённые скоупы) | бэкенд | когда-нибудь | отдельное решение | D39.37(9) | -| 44 | **Флор — выбор числа ПОСЛЕ ре-пробы 74; модель «thinking в completion» ПОЛУЧЕНА замером (D39.86): рычаг против неограниченного думания = `reasoning_effort`, флор не рычаг.** Мини-проба флора одобрена владельцем, промт не выдан; у dspro эффорт не настраивается (quirks 3а). Расхождение трекера с 74 снято D39.90. Археология дословно — `architecture/13-tech-debt-anchors.md` §Б-44. ⚠ **Вводная сменилась 13.08 (вахта §Б-108 СРАБОТАЛА):** вендор дал pro/flash настраиваемые уровни low/high/max — квирк 3а («у dspro эффорт не настраивается») устарел, пере-проба маппинга ПОВЕДЕНИЕМ + абсорбция в quirks — полигоном | бэкенд | когда-нибудь (триггер «приёмка 104» НАСТУПИЛ — D39.91, ручка заленжена; «сколько ставить» остаётся НЕзамеренным — нужен вариационный замер флора при `low`) | отдельное решение | D39.37(10), D39.86, **D39.90**, вендор 13.08 | -| 45 | `max_tokens`-упоры (две единицы) — вернутся на en-книге ; halve-chunk-on-retry (research/22 §2 №7) ОТКЛОНЁН D39.74 — вернуться сюда же при живых упорах | бэкенд | когда-нибудь | отдельное решение (с en) | D39.37(11) | -| 47 | M2-кэш / доктрина Д2 — кандидат на отдельную ратификацию | оркестратор/бэкенд | когда-нибудь | отдельное решение | D39.42 | -| 48 | Направленная банкнота — вернуться по замеру покрытия терминолога | бэкенд | когда-нибудь | отдельное решение | D39.42 | -| 48а | **Серийный шаринг банка** — РЕАЛИЗАЦИЯ (экспорт подписанного глоссария как сид-YAML следующей книги серии; спойлер-окна плющатся в since_ch=0); контракт round-trip держится тестом, самой фичи нет | бэкенд | когда-нибудь (перед второй книгой серии) | отдельное решение | D39.42 задел (а), PACK20_BANK_BUILD З-а | -| 48б | **Импорт «оригинал + чужой перевод» как режим данных терминолога** (target-агностичный вход есть контрактом; сам режим + провенанс источника + юр-сторона в юр-пакете) | бэкенд/владелец | когда-нибудь | отдельное решение + Ф2.5 (юр) | D39.42 задел (б), PACK20_BANK_BUILD З-б | -| 130 | **emitRankCap × writeAutoBank — ОСТАТОК после фикс-пака (D39.118):** $0-минимум ИСПОЛНЕН (дифф старого/нового авто-файла + WARN с именами выпавших; само-исключение сырого seed закрыто `unsignedEngineSurfaces` дофиксом приёмки); остаток = накопительный мердж авто-банка / освобождение слотов seed-rejects — СТОП-решение владельца (двигает банк → memory_version); материал для решения даст WARN со ВТОРОГО прогона (§6 п.8 отчёта пака) | владелец → бэкенд | когда-нибудь (гейт: WARN второго прогона) | СТОП-решение | D39.102 п.3, **D39.118** | -| 131 | **Кап инъекции не считает маркер и гендер-ноты**: `glossaryLineTokens` бюджетирует только «src → dst» (`memory.go:518-521` против рендера `:698-708`) — авто-книга (все строки Ambiguous с ⟨проверить⟩) превышает `glossary_token_budget` ~на 40–60% при budget 800; биллинг/потолки компенсированы (резервация по фактическому рендеру, `stagerun.go:469-477`), сам кап не исполняется. Фикс двигает состав инъекций → RequestHash → перекупка волн ⇒ СТОП-решение с названной ценой. ⚠ После строки 134 (единый блок, маркер снят с провода — D39.104) превышение пере-замерить: состав рендера сменится | бэкенд | когда-нибудь | СТОП-решение | D39.102 п.3 | -| 132 | **Стойкий (пост-ретрайный) аутедж ТОЛЬКО банк-провайдера валит весь ран** вопреки коммент-контракту «optional step never aborts» (`terminologist.go:630-634` — деградация только на ceiling; транспортные ретраи гасят transient, `httpllm.go:126-160`; потерь нет — чекпойнты реплеятся за $0): решить — деградировать в «термы неконсолидированы»+WARN либо честно переписать коммент | бэкенд | когда-нибудь | малое касание через СТОП-решение | D39.102 п.3 | -| **— ШОВ ДВИЖОК↔ПЛАТФОРМА: деньги и механизмы (D39.106/107 п.2) —** | | | | | | -| 136 | **Write-ahead intent + состояние `uncertain`-эскроу + `closing`**: холд НЕ освобождается по выходу юнита (сигнал обгоняет денежные события); spend не постится без свидетельства провайдера; расход сверх холда — полной суммой, превышение явной строкой убытка | платформа/бэкенд | скоро (промты по команде владельца) | стройка по research/25 | D39.106 | -| 137 | **Ночная сверка расходов с данными провайдера** (в движок цены входят float64 по ручной таблице `ledger/pricing.go` — систематика процентная; сверка приоритетнее споров об округлении) | платформа | когда-нибудь (до первого платного пользователя) | стройка по research/25 | D39.106 | -| **— НАХОДКИ ПРИЁМКИ ЭКСПОВ 18–20 (D39.108) —** | | | | | | -| 141 | **ОСТАТОК — работа В ДЕТЕКТОРЕ, и она НЕ про потерю текста.** ⚠ **Дыра, которой строка была заведена, ЗАКРЫТА лендингом D39.164:** сноска с ханьцзы («`[1] 蛊真人 — название романа.`») мимо детектора примечаний проходит по-прежнему, но поднимает класс `CJKLeak`, он `CosmeticOnly` (`backend/internal/checks/sanitizer.go:161-163`), юнит уходит `sanitizer_stripped` — и маркер дыры выдачи, заведённый паком «тихая порча», для НЕГО правдив. То есть читатель дыру ВИДИТ. Осталось: сноска БЕЗ ханьцзы («`[1] Название романа.`») не поднимает ни одного класса (замер сессии: `total=0`) и едет как есть — но текста при этом НЕ теряет, это лишняя добавка, а не дыра, и маркер на ней ДЕЗИНФОРМИРОВАЛ бы. Ловля таких сносок — правка самого детектора, отдельный предмет | бэкенд | когда-нибудь | правка детектора + тест | D39.108 (приёмка 20); половина закрыта D39.164 | -| 142 | **Механизм «гейты флагают → точечная починка по флагу» как прод-путь**: exp20 §3.3 — $0.0002/дефект, 12/12 (при ИДЕАЛЬНОЙ детекции); механизм конкурентов (research/22:179), у нас петля пака-16 за `enabled:false` (строка 13); детекторы «выдуманное слово»/«инверсия» прототипированы эксп-21. **ДИСПОЗИЦИЯ D39.117:** ОТКЛОНЁН как замена редактора (`C2/A_law` −3.75 Holm 0.0006; «$0.0002 чинит всё» мерилось при идеальных флагах и при реальной детекции пало), ПРИНЯТ формой «механический ПРЕ-ГЕЙТ перед редактором» — брак 5 клеток против 10/23 при половинной цене ($0.00298/$0.00602); ремонт ТОЛЬКО с банком (без банка ломает канон 0.917→0.895) | владелец → бэкенд | скоро (форма решена D39.117; ⚠ **порядок задан D39.190 п.3 — стройка ПОСЛЕ шагов 0–1 полигона**, а не по первой свободной смене) | бэкенд-промт | D39.108, **D39.117**, D39.190 п.3 | -| 143 | **Абсорбция норматива судейства в `09-pilot-protocol.md`**: разброс инструмента ДО замера · объявленный порог различимости · MQM-lite/error-span первичен, pairwise только для стиля · декой обязателен · запрет судьи семейства жильца арма | полигон/оркестратор | скоро ($0) | правка дока | D39.108, exp20 §7 | -| 144 | **Вахта: grok `reasoning_tokens` ВНЕ `completion_tokens`** — формула цены харнессов может недосчитывать (до $0.0325 на exp20); вендор-сверка биллинга xAI при следующем прогоне с grok | полигон | когда-нибудь (следующий xAI-прогон) | вендор-чек | D39.108 (приёмка) | -| 146 | **Два техдолга движка без строки трекера** (свип 08.08): `prices_checked` (120 д) гейтит read-only `report` и $0-resume — свежесть цен проверять только на ПЛАТНОМ пути (`03-implementation-notes:244`) · `cache_ttl` ↔ `cache_write_per_m`: цена записи в кэш задана под ОДИН TTL (5 м), при другом TTL расчёт врёт (`:246`). Оба жили только в справочнике якорей, то есть вне единственного трекера · **приёмка D39.134:** ценовой гейт держит и ДЕТЕКТОР самолечения деплоя — на стенде с протухшими ценами `status` даёт 10, а не 13, и цикл «поймал 13 → migrate → повтор» не наступает | бэкенд | когда-нибудь | малое касание | свип доков 08.08, D39.134 | -| 147 | **Транспортные частичные из research/21 без носителя** (свип 08.08): п.16 HTTP/1.1-escape на последней попытке как ДИАГНОСТИКА тихого усечения 2–8k [PARTIAL, GATED] · п.17 assistant-prefill continuation на `finish=length` вместо ре-рана всего вызова [PARTIAL, DEFER]. Оба помечены в ресёрче как отложенные и ни в одной строке трекера не появились | бэкенд/полигон | когда-нибудь | замер → решение | свип доков 08.08, research/21 §16–17 | -| 150 | **Sol-арбитраж — внешний контур вместо слепого чтения владельца**: пере-суд расходящихся контрастов эксп-21 (`A/F`: luna +0.84 против gemini +3.03 — расхождение 14 sd шума судьи-замены) и слепых пар эксп-22 руками владельца через подписку (третье семейство, high reasoning); пакеты готовит эксп-22 Ф0.4 (слепые метки · оба порядка · декой), транскрипты персистятся как голоса внешнего судьи; luna-клетки Sol не судит (своё семейство) | владелец + полигон | скоро (пакет арбитража — из существующего сырья) | эксп-22 Ф0.4 + руки владельца | **D39.117** | -| 151 | **Отказной режим связки**: эхо-мина черновика воспроизводима на материале (глава 11 — 3/3 попыток; частота 31% на zh), связка покрыла 9/10 подряд идущих глав против 10/10 у однопроходки — единственный довод ПРОТИВ связки во всём эксп-21; движку нужен fallback при невозможности годного черновика (вариация ре-гена · эскалация модели черновика · деградация в однопроходку) | владелец → бэкенд | когда-нибудь (до МАСШТАБА) | СТОП-решение | **D39.117**, exp21 §14 | -| 152 | **Слипание абзацев — слепое пятно детерминированного контура**: батарея на тех же текстах даёт ДРУГОЙ порядок армов (`D` — худший по судье — лучший по правилам), расхождение локализовано в слипании, которого не проверяет ни одно правило; правило в батарею полигона + кандидат в гейты движка | бэкенд/полигон | когда-нибудь | малое касание + тест | **D39.117**, exp21 §13 | -| 153 | **Чистый контраст мандата перевёрстки**: `D/D_` загрязнён (объём промта ×1.92 + вёрсточная строка + правило чэнъюй); уравненные промты и пере-гон ≈$0.35; по грязному контрасту мандат ВРЕДИТ по оси ФОРМА (−1.09 из −3.31 `D/A`) | полигон | когда-нибудь (опция эксп-22 Ф3 — реши сессия) | замер | **D39.117**, exp21 §16.3 | -| **— ХВОСТЫ ФИКС-ПАКА БАНКА (D39.118) —** | | | | | | -| 154 | **Одноруновая голова семьи** (`蛊`/`转`/`窍` едет в отдельном вызове от 12 своих поверхностей — якорь семьи обязан быть ≥2 рун) — включается ОДНОЙ строкой данных `family_containment_runes han 1`, Go не трогается; не включена: цена в размере юнитов не замерена | бэкенд | скоро — ✅ **ГЕЙТ СНЯТ 05.09: поле ПРИЕХАЛО.** Манифест публикует размер юнита в знаках — `source_chars` (плюс раздельно плотные/разрежённые), лендинг `81a89e9`, акт D39.206, **аддитивно, версию манифеста не двигало**. ⇒ «решение уровня ноты» больше не нужно, замер берётся. Ниже — археология гейта. ⚠ **ГЕЙТ ПАЛ И ОКАЗАЛСЯ НЕДОСТИЖИМ** (испр. 02.09, переведена из БЛИЖНЕГО веса): первый холодный прогон отработал 31.08, и он же показал, что назначенный замер этим путём НЕ БЕРЁТСЯ — манифест не публикует размеров юнитов В ЗНАКАХ вовсе (юнит несёт `id`/`first_*`, не длину). ⚠ Настоящее предусловие — новое поле контракта манифеста, то есть решение УРОВНЯ НОТЫ (`manifest_version`), а не строки бэклога: до него строка не гейчена ничем достижимым | строка данных по замеру | **D39.118**, отчёт §5 | -| 155 | **Скрипт-слепой резолв семей/серий**: han-правила режут кану и хангыль (синтетика: 24 катаканных имени с общим アリ → батч 8036 рун при бюджете 6000); живого вреда нет — пары в репо нет; та же слепота у серий уже в HEAD | бэкенд | когда-нибудь (преп ja→ru, с 81/120) | ja-пак | **D39.118**, отчёт §5 | -| 156 | **`banknote_truncated` — ПОЛ, а не счёт**: обрыв, срезавший сам разделитель, флага не даёт; буквальный фикс зажёг бы колонку на каждом обрыве в прогонах без канала — нужен гейт по `Gates.Banknote.Enabled` | бэкенд | когда-нибудь | малое касание | **D39.118**, отчёт §5 | -| 157 | **Пере-подтвердить `family_max_members=24` и `families_held`** на длинной книге (24 калиброван на дистилляции в 150 поверхностей; кап эмиссии 200 + реверс-секция дают другой список); если `families_held` велик — ослабить гард до «родство по любому члену юнита» вместо «по корню серии» | бэкенд | когда-нибудь — ⚠ **ГЕЙТ ПАЛ 31.08, ответ ОТРИЦАТЕЛЬНЫЙ** (испр. 02.09, переведена из БЛИЖНЕГО веса): прогон дал `families_held=0`, значит ослаблять гард не нужно. ⚠ Но замерено на ДЕСЯТИГЛАВНОЙ книге, а строка требует пере-подтверждения на ДЛИННОЙ — вывод действителен «на 10 главах» и протухнет на первой длинной книге. Указатель «§6 отчёта» заменён на греп-форму: `archive/reports/COLDRUN_V16_REPORT_2026-08-31.md`, греп `families_held` | замер → решение | **D39.118**, отчёт §7 п.7 | -| 158 | **Уверенность не гейтится данными пары**: канал снимает третью колонку у любой пары, чей промпт её попросит; у пары с ДВУХпольным промптом узкий риск «Пик␣␣99» (число ≤100 за двойным пробелом уедет в conf); при нужде — дата-декларация пары | бэкенд | когда-нибудь | дата-декларация | **D39.118**, отчёт §4 п.6/§7 п.8 | -| 159 | **Durable-имена эвиктнутых** (`retrieval_state.evicted_detail` = миграция; сегодня лог, и приёмка ратифицировала «этого достаточно») — заводить только при доказанной потребности, одним касанием с идемпотентностью миграций 49а | бэкенд | когда-нибудь (гейт: доказанная потребность) | миграция с 49а | **D39.118**, отчёт §7 п.2 | -| 160 | **Структура глав, Этап 0** ($0, wire-нейтрально): `titleRaw` в манифест (subtitle добывается `matchHeaderLine` и ПОНИЖАЕТСЯ в тело прозы (испр. D39.125), а не выбрасывается) + provenance у heading + тип chapter/fragment + вердикт структуры (бамп manifestVersion) · **дыра Р6**: projectRebill слеп к контент/позиционной оси (rebill.go:32-35) — ревизия структуры перекупила бы хвост МОЛЧА, закрыть read-path-расширением · слой пользовательских правок отдельным сайдкаром · **зонная половинка темы:** Ф-30 фронта / В-4 владельца (глава без заголовка на экране — метка из ДАННЫХ, К-3) ждут ровно эту строку; `heading` манифеста до неё = ВРЕМЕННЫЙ рендер движка (D39.122 п.2д) | бэкенд | скоро (ГЕЙТ ПАЛ словом владельца 15.08, D39.136 п.3: ставится ближайшим бэкенд-паком с мандатом максимального качества; ⚠ **испр. 05.09: блокер 236 МЁРТВ** — «писатель книги» закрыт D39.175 (30.08), и очередь его больше не держит. Живая диспозиция другая: **строка отложена ПОРЯДКОМ — D39.190 п.2**, то есть ждёт своего окна, а не предшественника; тесты структуры глав — узлом будущего холодного прогона) | пак | research/27 §6 Этап 0, D39.122 п.4, D39.136 | -| 161 | **Структура глав, Этап 1 «большой перекрой»** (единственное дешёвое resnapshot-окно — пока платная книга одна, ДО интейка): IR + формато-адаптеры (epub nav/NCX, fb2) + индуктор с валидаторами и вердиктами + третий версионный план паттернов (не в снапшот волн) + развязка чанкера от глав + банк-окна на chapter-ID + контент-адресуемый resume (долг D15.2) + формула Chapter.ID «окно» + роль title (мини-сессия названий: редакторский слот · инъекция банка · двухфазно вокруг подписи) + аддитивное расширение контракта 14; жизненный цикл дерева — research/27 §3а (решение владельца 09.08) | бэкенд (+фронт/платформа аддитивно) | скоро (постановка санкционирована D39.136 п.3: СНАЧАЛА дизайн-пак с мандатом максимального качества, стройка после ратификации дизайна; ⚠ дешёвое окно закрывается первой книгой внешнего пользователя) | дизайн-пак → ратификация → пак(и) | research/27 §3/§5/§6, D39.136 | -| 162 | **Структура глав, Этап 2**: in-band метки глав в потоке перевода (третий эшелон детекта + коррекция структуры по ходу черновой волны, §3а п.3) + канон-гейт названий ($0) + миграционные карты якорей (same/moved/split/merged/gone/new) + калибровочный корпус детекта в CI ⚠ Форма владельца 30.08: черновая модель отвечает МЕТАДАТОЙ в конец ответа, если посчитала строку фрагмента авторской разметкой главы — разметка едет попутно с черновиком без отдельного платного прохода; доверие — через фиксацию в манифесте и подтверждение спорных. | бэкенд + полигон | когда-нибудь (после Этапа 1) | пак + корпус | research/27 §5/§6 Этап 2 | -| 163 | **Версии модулей x/text|x/net двигают нарезку МИМО всех ключей** (NFC в NormalizeSource — таблицы модуля, не тулчейна; epub-токенайзер): бамп `go get -u` тихо меняет нарезку при свежих на вид манифесте/чекпойнтах/снапшоте — класс всей чекпойнт-плоскости, унаследован манифестом; вплести версии модулей (debug.ReadBuildInfo) в NormVersion/chunkerVersion либо явный запрет бампа без `--resnapshot` | бэкенд | когда-нибудь (до второго прогона книги) | малое касание | **D39.122**, приёмка (охотник №1) | -| 164 | **Rebill-проекция `status` с nil baseMemory завышает RebillUSD**: read-путь не материализует base-банк → renderedContentHashes даёт пустую инъекцию → repin недоопознан, строка считается re-pay (консервативная сторона, но противоречит комменту «status can never quote a different number than translate»); материализовать base-банк на read-пути либо смягчить клейм | бэкенд | когда-нибудь | малое касание | **D39.122**, приёмка (охотник №1); preexisting | -| 166 | ⚠ **ДВИЖКОВАЯ ПОЛОВИНА ПОСТРОЕНА 05.09** — `expected_usd` по главам, `book_once_usd`, `step_max_usd` в `manifest --json`/`status --json` (лендинг `81a89e9`, акт D39.206). Открыта ПЛАТФОРМЕННАЯ: числа публикуются и никем не читаются (`git grep -lE "StepMax|step_max" -- platform/` пусто). **Движковая поверхность оценки $/глава** (ставка-константа платформы $0.03 из exp08 v2 — временная мера беты, П-10 зоны платформы; честная оценка по книге/паре — движковая) | бэкенд | когда-нибудь | отдельный пак | D39.123 | -| 168 | **Состав волн пайплайна = пар-конфиг (данные), не общий хардкод**: вопрос владельца 10.08 «нормально ли под китайский строить весь бэкенд и конфиги?» — жильцы ролей и промпты уже конфиг/langpacks, но ТОПОЛОГИЯ волн (перепис · точечный edit-контур · без второго прохода) одна на всех пар; если фаза Д покажет разных победителей по парам (H-3/H-4: en-черновик+edit против zh-связки), состав волн уезжает в пар-конфиг данными; ревью-вопрос общности §0 `12-go-style-notes.md` | бэкенд | когда-нибудь (после данных фазы Д) | замер (фаза Д) → решение владельца → малое касание | слово владельца 10.08, промт фазы Д | -| 170 | **`tmctl init` — движок сам заводит книгу** (форма В развилки интейка): платформа зовёт $0-команду, движок пишет СВОЙ `book.yaml` — требования к полям живут там же, где проверяются (`config/book.go`); до неё бета живёт формой Б (рендер из деплой-шаблона платформой при создании книги, ратификация D39.130) | бэкенд | когда-нибудь (после беты формы Б) | малый пак | приёмка P5, **D39.130** | -| 172 | **Остаток после пере-пина DeepSeek (пин ИСПОЛНЕН и ПРИНЯТ — D39.137, `76049bb`):** (а) **схемное решение владельца по time-based** — доклад §5 отчёта вендор-сессии (рекомендация: пик оставить; scheduler-вариант строки 60 не начинать до ответа вендора «по какой отметке времени тарифицируется вызов» — вендором НЕ задокументировано — и замера доли пика; дешёвый рычаг: операционное правило «прогоны не стартуют в 01–04/06–10 UTC» — почти всё ×2 без строчки Go; гибрид «резерв пиком, сеттл по окну факта» назван) · (б) пере-калибровка ставки $0.03/глава (166/П-10; множитель счёта замерен) · (в) exp08 v3 (85) обязателен до budget_usd · (г) **вахта весов V4-Pro-0813** (класс D39.61): риг готов, порог ратифицированной ВЫБОРОЧНОЙ формы («≥4/5 прогонов N=5 достигают 6/6», D39.136 п.6б) **в риге ИСПОЛНЕН** паком честности — арифметика вынесена в `live_reprobe_threshold_test.go`, сам риг применяет её же. ⚠ **ИМЯ СТРОКИ ВВОДИТ В ЗАБЛУЖДЕНИЕ (испр. №18 17.08, сверено кодом):** названный риг меряет роль КЛАССИФИКАТОРА, а она ходит на **flash** (стендовый `pipeline.yaml:64` + артефакт прошлого прогона `model = deepseek-v4-flash`), тогда как сменившиеся веса — у **pro**, а pro у нас = РЕДАКТОР (`configs/pipeline-c1.yaml:62,76`). Владелец 17.08 санкционировал ТОЛЬКО вариант (а) — пере-съём классификаторного гейта, потолок $0.20, исполняется п.5 пака честности. **По этому прогону строку НЕ закрывать:** вопрос «сменились ли веса редактора» остаётся открытым, дешёвый вход к нему — данные фазы Д, где pro гоняется именно редактором (спросить полигон прежде, чем покупать новый замер) | владелец → бэкенд/полигон | скоро (схема — на владельце; вахта — после 16.08) | СТОП-решение (схема) + замер (вахта) | вендор 13.08, **D39.137**, строка 60, D30.4 | -| 180 | **`prices_checked` — одно поле на ВСЮ таблицу цен** (находка вендор-сессии, D39.137): бамп по факт-чеку одного вендора сдвинул 120-дневный гейт свежести остальным семи моделям (дедлайн уехал ~07.11→~13.12); лечение — пер-модельная дата проверки (правка схемы) ЛИБО ре-чек остальных вендоров отдельным заходом до исходного дедлайна | бэкенд | когда-нибудь (ре-чек вендоров — до ~07.11) | малое касание / вендор-заход | D39.137, отчёт §7.1 | -| 182 | **Wire-батч перед добором идеала — КОПИТЬ и вносить ОДНИМ касанием** (каждая правка двигает RequestHash / `memory_version` / снапшот = перекупка волн; дриблить по одной = платить пере-снапшот несколько раз): 46 экран цели (+предпосылка 113 фикстура) · 134 инжект-заголовки (гейт пал D39.108) · 131 кап инъекции · 140 банковый контур в shipping (СТОП-решение) · 105(а) вердикт-половина классификатора · 130-остаток (мердж авто-банка, гейт WARN второго прогона) · 14 ё-фолд (носитель «следующий пак общности») · **119+124(+115 пер-парный хеш EmbeddedVersion) — ОДНИМ дизайн-паком** (строка 124 требует принимать целиком; сверено кодом: `cutTag` фолдит `chunkerVersion`/`EmbeddedVersion`/`NormVersion` — `manifest.go:160-169`); вне батча свободен только 118 (tools/go.mod). Состав — аудит корпуса 15.08 (archive/reports/CORPUS_AUDIT_2026-08-15.md §В.г) | оркестратор → бэкенд | скоро (собрать к ратификации фазы Д; вносить перед первым платным прогоном добора идеала) ⚠ **СОСТАВ ОКНА 04.09 (D39.190 п.4 ратифицировал пере-снапшот единым актом):** в выданный вайр-батч вошли **210 · 113→46 · 134 · 140 · 184(а)**; СНАРУЖИ остались и это сказано вслух, а не умолчано — **131** (кап инъекции: своя цена и своё СТОП-решение, и сама строка велит «пере-замерить ПОСЛЕ 134», то есть её очередь следующая), **105(а)** и **14** (ждут следующего окна), **119+124+115** (только одним дизайн-паком), **160** (бампает `manifestVersion`, отложена ПОРЯДКОМ — D39.190 п.2), **142** (после шагов 0–1 полигона — D39.190 п.3). | координационная строка → промт(ы) батча | аудит 15.08, D39.134/136/137 | -| 173 | **`backupStamp` секундной точности**: два `translate` в одну секунду дают коллизию имени бэкапа и exit 1, маскируя класс «проект занят» (12) — метка до наносекунд/uniquify либо распознавать коллизию явно; преexisting, вскрыт ревью эмиттер-пака | бэкенд | когда-нибудь | малое касание | приёмка D39.131 | -| 175 | **Деплой движка «в полёте» — ДАЛЬНИЙ ОСТАТОК** (ближняя половина ИСПОЛНЕНА паком migrate — D39.134; правило свипа и settle запиненным бинарём — аддендум P6, D39.132). Остаток: (а) при СЛЕДУЮЩЕМ бампе схемы проставить в файл книги `application_id` + `min_reader_version` — данные-задел под окно совместимости, ~0 логики; (б) GC бинарей: удалять не пиненные ни одной незакрытой попыткой, последние 2–3 релиза держать для отката; (в) окно совместимости читателей / пин уровня книги — строить ТОЛЬКО по триггерам: много тенантов · бампы схемы еженедельно+ · потребители `status` кроме платформы. Археология захода — ресёрч 14.08 (вывод: exact-match читателей на деньгах = осознанный fail-closed, корень не выдёргивать, приделать дверь) | платформа/бэкенд | когда-нибудь (по названным триггерам; (а) — попутно первым бампом схемы) | данные-задел + малые касания | владелец 14.08, ресёрч 14.08, строка 139, D39.134 | -| 177 | **Гигиена restore point `tmctl migrate`** (находки приёмки ВНЕ карты отчёта; фикс-лист ФМ — запись приёмки 15.08, слайс [archive/PROGRESS-2026-08-14-15.md](archive/PROGRESS-2026-08-14-15.md)): ретрай в ту же секунду после сорванного шага = exit 1 «backup already exists» вне полосы — ровно на цикле самолечения платформы · kill -9 посреди шва оставляет РВАНУЮ копию под легитимным именем (ручной откат по ней = потеря данных; лечение — temp+rename) · копии restore point не подчищаются (повтор после срыва копит их) · SIGINT/SIGTERM в migrate не прерывают (ctx не доезжает) · комментарий migrate.go «no money touched» на no-op неверен (recovery зануляет leftover reserved) | бэкенд | когда-нибудь (следующее касание migrate/бэкапа) | малое касание + тесты | D39.134, приёмка №17 | -| 178 | **Калибровка `sense` банка** — слово владельца 15.08 (D39.136 п.4б): смысл должен быть «ёмкий и достаточный на всю книгу, но не слишком подробный» (образец: «спутница главного героя»); сейчас возможно КОРОТКОВАТ; замер длины/достаточности на подписанном банке → правка промптов банкноты/терминолога (двигает провод — цену назвать при внесении) | бэкенд/полигон | когда-нибудь (касание банка) | замер → правка промптов | D39.136 п.4б | -| 183 | **Батч 0.3.0 — ОТРАБОТАН ЦЕЛИКОМ** (батч D39.142 + дофикс D39.143, `86720cf`; промт в архиве). ⚠ Номер канона в этой строке НЕ держим — канон ушёл на **0.9.0** (D39.180), лента миноров — в шапке. **ЖИВОЙ ОСТАТОК ОДИН — (б):** зеркало `frontend/docs/api-contract/` + типы + моки + гейт утечки, первое касание фронта при разморозке; расхождение канона и зеркала ВРЕМЕННО ратифицировано D39.142 п.5. Пункты (а) и (в) СНЯТЫ (D39.153; D39.144 п.4)| оркестратор ⚠ **ОЦЕНКА «ПЕРВОГО КАСАНИЯ» ЗАНИЖЕНА — измерено 05.09 веером.** Записанное «синк зеркала + перегенерация типов ОДНОЙ командой» неверно по ОБЪЁМУ: перегенерация — одна команда, но она вскрывает переписывание слоя данных. Замерено: 16 операций против 21; 40 новых имён схем в каноне и 10 МЁРТВЫХ в зеркале, на которые `src` ссылается 31 раз; две ручки, которых платформа не отдаёт вовсе. Плюс гейт версии у фронта читает СВОЁ зеркало (строка 268), то есть отставание он не увидит и после синка. | скоро (остаток = только (б) зеркало фронта при разморозке) | P7 → фронт при разморозке | D39.138, D39.142, **D39.143** | -| 185 | **Дописывание глав в ТЕКУЩУЮ книгу («костылей не будет»):** форма `POST /books/{id}/parts` + ответ «сколько глав добавится, что сдвинется и почём» ДО подтверждения; экономика уже позволяет В КОНЕЦ за ~$0.02 (ключ вызова позиционный, исходник вне снапшота), вставка в середину = МОЛЧАЛИВАЯ перекупка хвоста ~$9–11/500 глав — движковый гейт против молчания ОБЯЗАТЕЛЕН (родня дыры Р6 строки 160); платформа второй файл принять не может (re-parse нет); ja-мина: новый ruby-алиас двигает `memory_version` → снапшот (громкий `--resnapshot`, уточнение приёмки); полный $0-резюм хвоста — предусловие D15.2 (строка 49) | бэкенд+платформа+контракт | когда-нибудь (вместе со строками 160–162 — дизайн в паке 161) | дизайн-пак 161 → стройка | research/28 Б-19а/§8 п.7, D39.138 п.2г | -| 186 | **Сеть: перечитывания ничем не удешевлены** (замер 16.08: дерево 2283 глав = 250 КБ на каждый кадр `status`, фокус-рефетч 12 вкладок = 562 КБ — самый частый трафик порождает переключение вкладок, не пайплайн; гипотетический кадр банка на главу = 372 МБ/прогон; сжатия/ETag/304 нет НИГДЕ): план по эффекту — (1) gzip на текстовых ответах, НЕ на SSE (2) `ETag`/`If-None-Match`→304 на списочных GET (3) скоуп в кадре (id+версия, БЕЗ текста) (4) дельта-чтение банка/замечаний `?after_version=` (5) `staleTime` у клиента; шаги 1–2 — платформа (её же `platform/docs/PLATFORM_DIRECTION.md`, греп `Условные запросы`), семантика — в спеку батчем 183; транспорт НЕ менять (решение владельца по §5б) ⚠ **ШАГИ 1–2 ПОСТРОЕНЫ И ЗАЛЕНДЕНЫ P7 (D39.153)** — gzip на JSON и НЕ на SSE + `ETag`/`If-None-Match`→`304` на коллекциях, карточке книги и `/capabilities` — **и ПЕРЕ-ПРОВЕРЕНЫ ЗАМЕРОМ 28.08** (воркфлоу-ревью P9 на стенде, приёмка D39.162): банк 437 Б холодным → повтор с `If-None-Match` даёт **304 / 0 Б**; юниты главы 3008 Б → **740 Б gzip (×4.1)**; ниже порога 1024 Б gzip честно НЕ применяется; SSE корректно не сжимается. Остаток — шаги 3–5 | платформа (+контракт/фронт) | скоро (остаток: шаги 3–5) | мидлварь/edge платформы + батч 183 + разморозка фронта | research/28 §5б/Б-11а, D39.138 п.2д | -| 188 | **Носитель события «ре-проба 74»** (аудит D39.140: событие ждали строки 5 · 36б · 44 и шапка CURRENT-STATE, а владельца у него не было — строка 74 закрыта D39.91): дешёвая ре-проба flash при ПЕРВОМ платном прогоне добора идеала (D39.63 п.4) + слоты, подвешенные на неё: рецензент спорных кластеров банка (остаток 5) · замер второго мнения (36б) · выбор числа флора (44, после одобренной мини-пробы) · итерация №2 редакторов (D39.22/63) · выборочный порог 116 в риге (дописка 172-г) · решение о включении ре-гена перед эскалацией (экс-77, D39.64: «включение — решением при ре-пробе 74»; ручка построена, мертва во всех конфигах, ре-ген ≈7.6× дешевле эскалации) | полигон/бэкенд | скоро (гейт добора идеала — первый платный прогон) | проб-пакет при первом платном прогоне → решения по слотам | D39.63 п.4, D39.91, аудит D39.140 | -| 189 | **Мультиязычность фраз ЛОГОВ и АРТЕФАКТОВ движка — вторая половина слова владельца 15.08** (D39.136 п.4а «фразы ВСЕХ зон»; первая половина — юзерский провод — решена ревью 28 Б-1/батчем 183): фразы в `bank-stop`/статусных артефактах и логи движка вне контракта, носителя не было (research/28 §6, строка Ф-61: «носителя назвать отдельно» — аудит D39.140 подтвердил: не назван); разобрать, что из этого читает ПОЛЬЗОВАТЕЛЬ (артефакты банка — да, через проекцию платформы) и что оператор (логи — легитимно английские) | бэкенд | когда-нибудь (до второй локали интерфейса) | разбор → точечная правка | research/28 §6, D39.136 п.4а, аудит D39.140 | -| 190 | **Кросс-СЕМЕЙНЫЙ проход контракт-ревью** (не-Claude опровергатели; буква заказа владельца D39.136 п.5 «кросс-модели», исполненная в ревью только кросс-тирами Claude — ограничение честно заявлено research/28 §7/§10): проверка вердиктов доклада моделью другого семейства полигонным контуром; жила только колонкой «ЖИВОЕ» реестра нот — аудит D39.140 дал строку | полигон | когда-нибудь (после фазы Д; перед лендингом батча 183 — если владелец захочет второй рубеж) | полигон-слот с внешним провайдером | research/28 §10, аудит D39.140 | -| 192 | **Пост-ридинговый цикл правок банка — «наше подумать» владельца 16.08 (записано, чтобы не потерялось; точную механику «не продумал ещё никто и нигде» — его слово).** UX-модель целиком: юзер нажал перевод → черновая волна + майнинг вместе → на фронте появляются ЧЕРНОВОЙ перевод и ЧЕРНОВОЙ банк · подписывается ВЕСЬ банк одним ОК (D39.144) → перевод уходит в доработку · дальше юзер ЧИТАЕТ, и его опции: поправить термин в банке ЛИБО добавить свой → кнопка «поправить» → пере-генерация, которая по ВХОЖДЕНИЯМ правит запрошенное. Открытые вопросы дизайна: что именно перегенерируется (вхождения ключа · затронутые юниты · со сметой и согласием?) · нужен ли движковый ТОЧЕЧНЫЙ РЕДАКТОР (полигон над этим работает — фаза Д) · форма в контракте (ручки нет) и на экране. Уже лежит под ногами: движковый re-edit по ключу банка со сметой и $0-пере-пином ПОСТРОЕН (строка 49: `repin.go`/`rebill.go`, D39.42 п.5/D39.45) · пометка неподписанных строк · дельта-чтение банка (0.3.0). НЕ проектировать до полигонных итогов; затем дизайн-пак на их результатах → слово владельца → стройка | владелец+полигон → бэкенд/контракт/фронт | когда-нибудь (триггер: итоги фазы Д по точечному редактору) | дизайн-пак после полигона → слово владельца → стройка | слово владельца 16.08, D39.144 п.1 | -| 195 | **ОСЬ «идентичность оплаченной работы» — переселена в дизайн-пак 124 (решение владельца 17.08, вариант А; D39.151).** Как САМОСТОЯТЕЛЬНАЯ стройка ЗАКРЫТА: маркер `snapshot_id`/`run_id` на `checkpoints` отдельной колонкой НЕ строится. Причина — внешний разбор опроверг посылку «колонка = тождество»: $0-пере-пин законно переносит строку на новый снапшот со СТАРОЙ ценой (`stagerun.go:96-105`, сверено оркестратором), у старых чекпоинтов бэкфилла нет вовсе (`jobs.snapshot_id` перезаписывается каждым ре-снапшотом) ⇒ вывод-обход остаётся в коде навсегда как legacy-ветка, а колонка лишь добавляет рядом второй путь. **Настоящий корень глубже:** в сторе нет первоклассной связи «строка диспозиции ↔ вызовы, которые её оплатили»; снапшот на чекпоинте — прокси, а не примитив. ⚠ Границы семьи сужены тем же разбором: 49 и 195 — про РАЗНОЕ (49 = когда переиспользование законно, 195 = как честно посчитать будущую покупку), общий у них субстрат, не задача; из 124 родня только ось (в). **Срочности нет:** под контрактом D39.150 («направление ошибки, не точность») ни один исход не занижает молча — недостача несётся историческими деньгами С РАСКРЫТИЕМ, пойманный откат называется вслух. Остаточные нарушения контракта чинятся БЕЗ схемы: 197 и 194 | бэкенд | когда-нибудь (гейт — триггеры пака 124: дописывание глав 185 · МАСШТАБ · первый внешний потребитель числа) | ось дизайн-пака 124 | **D39.151**, внешний разбор 17.08 | -| 196 | **Остаточный класс строки 176: неперехватываемые `fatal error` Go** (конкурентная запись в map, OOM, стек-оверфлоу) по-прежнему дают exit 2, то есть читаются платформой как «завершено с флагами» — `recover` их не ловит по устройству языка (подтверждено линзой шва исполнением). Строка 176 закрыта для ПАНИК, не для fatal. Лечение — вне exit-контракта: сторож процесса у платформы либо маркер живости в артефакте прогона | бэкенд/платформа | когда-нибудь | отдельное решение | приёмка №18, линза шва | -| 197 | **Фикс-лист приёмки пака честности ФЧ-1…ФЧ-8** — восемь пунктов класса «заявленное не прибито» и «текст обещает больше числа», ни один не блокировал лендинг. **Тело списка дословно, с весами и с секцией «что НЕ проверено», — [archive/PROGRESS-2026-08-17.md](archive/PROGRESS-2026-08-17.md), запись приёмки №18** (D39.149). Здесь держим только ратифицированное: **ФЧ-5 РЕШЁН владельцем 17.08 (D39.150): прайсить по модели, которую стадия резолвит СЕЙЧАС, + округление вверх и оговорка в тексте согласия.** Носителя-сессии НЕТ — по слову владельца 17.08 пока только записано | бэкенд | скоро (следующее касание денежного пути; ФЧ-5 обязателен до первого пере-прогона со сменой модели) ⚠ **СОСТАВ ПЕРЕ-СКОУПЛЕН 04.09:** ФЧ-1/ФЧ-4/ФЧ-5 закрыты паком «число согласия» (D39.187); **ФЧ-6 по коду выглядит ЗАКРЫТЫМ** — отказ проекции репортится базисом, отчёт не валится (`backend/internal/pipeline/status.go`, греп `RebillBasisFailed`); **ФЧ-7 отдан проверкой** в вайр-батч (воспроизвести панику поверх пойманного потолка, чинить только если воспроизводится); **ФЧ-2/ФЧ-3/ФЧ-8 НЕ ПРОВЕРЕНЫ никем** и остаются живым остатком строки. | дофикс-промт ЛИБО попутно ближайшим паком | **D39.149**, **D39.150** | -| 198 | **Апгрейд движка стирает замечания и счётчики книги БЕЗВОЗВРАТНО — композиция двух половин, каждая известна по отдельности** (приёмка P7, линза «вне карты», обе половины пере-прочитаны оркестратором). Платформа при смене `manifest_key` сносит ВСЕ `unit_resolutions` книги (`platform/internal/pgstore/readmodel.go:164-165`), рассчитывая, что поток их пере-наполнит; движок анонсирует юнит РОВНО ОДИН РАЗ за жизнь книги — ключ `unit::::` БЕЗ метки нарезки (`backend/internal/pipeline/events.go:399-400`), а леджер анонсов переживает прогоны (`backend/internal/store/outbox.go:96` «already announced… by one that ran before it») ⇒ совпавшие координаты не переанонсируются НИКОГДА. Обостряется порядком: долг на материализацию ставится только на ГРАНИЦАХ работы, поэтому первая зачистка после апгрейда случается в КОНЦЕ первого пост-апгрейдного прогона и сносит замечания ТОГО ЖЕ прогона, за который заплачено. Следствия на проводе: «0 из N» на переведённой книге навсегда · шкала снова предлагает купить переведённое · замечания читателя исчезают. **Лечится с обеих сторон:** движковая половина — метка нарезки в ключе анонса (решение зоны движка), платформенная — не сносить вслепую либо восстанавливать из экспорта. ⚠ Гейт холодного прогона: смысл упражнения — гонять книгу против МЕНЯЮЩЕГОСЯ движка, то есть первый же апгрейд обнулит библиотеку | бэкенд + платформа | **скоро (до первого реального пользователя И до холодного прогона с апгрейдами)** | связка: решение по ключу анонса в движке → правка платформы | приёмка P7 (D39.153) | -| 201 | **Движковое «Глава N» доезжает читателю ВНУТРИ текста, обходя дисциплину `heading: null`** (линза шва P7, пере-прочитано оркестратором): `backend/internal/pipeline/export.go:58`=`ApplyHeading` (испр. оркестратором №20 30.08: якорь уезжал с `:230` и с `:266` — код растёт) приклеивает детерминированный порядковый к экспортному тексту первой юнит-главы (`ce.FinalText = chunk.ApplyHeading(...)`), колонка `Source` при этом остаётся heading-stripped. Платформа переносит обе как есть и честно отдаёт `heading: null` — то есть клиент нарисует СВОЙ порядковый на языке своего интерфейса над абзацем, который уже начинается с русского «Глава N», а исходная колонка соответствующего маркера не несёт: пара визуально рассинхронизирована на каждой первой главе. Конкретное следствие открытого К-2 контракта; родня движковой строки **160** (глава без заголовка) | бэкенд | когда-нибудь (с 160) | отдельное решение | приёмка P7 (D39.153) | -| 203 | **Хвосты контракта после синка 0.4.0 — ОТКРЫТ ОДИН ПУНКТ, остальное исполнено** (тела релеев — `platform/docs/archive/P7_ACCEPTANCE_HANDOFF_2026-08-17.md` §7; сюда переписан НЕ текст, а статус — один носитель на факт). **ИСПОЛНЕНЫ и сверены грепом при лендинге:** (а) минором 0.5.0 (D39.161) · (б) · (д) · (и) поле `stop_requested` (D39.152) · (л)(м)(н)(о) контрактной сессией — остаток по фразам Приложения А несёт строка **204** и лист владельца. **(г) наполовину** — `unspecified` ратифицирован в каноне (`docs/architecture/14-api-contract/openapi.yaml:2168`=`is reserved and is the server`), открыта только ГРАНИЦА ступеней замечаний (две ступени при девяти рангах движка); ⚠ её прежний носитель — строка 148 — СНЯТ 21.08 по слову владельца. **(з) СНЯТ как ратификация 22.08 сквозной трассировкой (разбор, на который ссылается строка 191):** конфликта моделей НЕТ — гейт движка проверяет полноту не ПОДПИСЕЙ, а ФАЙЛА решений, и ОДИН файл со всем банком его снимает (`loadMinedDelta` штампует только `Source`, `mining.go:855-867` → опущенный статус дефолтится в `approved`, `membank/memseed.go:130`=`status = "approved"` → `unsignedEngineSurfaces` выбрасывает лишь `Source=="mined" && Status!="approved"`, `mining.go:710-719`). Пере-диспозиция 27.08 (D39.158 п.7): движковый гейт полноты УСТРАНЁН, не обойдён; остаётся снять обход в платформе — одна боевая строка (`platform/internal/runs/spawn.go`, `--verify-bank` не передаётся на resume) плюс семь строк ставшего ложным обоснования, работа платформенного пака. **ОТКРЫТО РЕАЛЬНО — (к):** ключ `project_db` в `book.yaml`, договорить, кто им владеет: шаблон оператора его не содержит, движок делает необязательным. ⚠ Следствие «на штатном деплое банк не читается» ОПРОВЕРГНУТО живым кодом: путь публикует ДВИЖОК конвертом артефактов, пустой путь — ГРОМКИЙ отказ (`platform/internal/runner/artifacts.go:39`=`the engine published no bank read-out path`); остаток (к) чисто договорной| контракт/доки | скоро (следующее касание контракта) | контрактная сессия | приёмка P7 (D39.153) | -| 204 | **Движок не публикует причины флагов ДАННЫМИ — карта причин у платформы рукописная и расходится молча** (релей §7(в) хендоффа P7; зона платформы в чужой бэклог не пишет и просила строку сюда — `platform/docs/archive/platform-PROGRESS-P7.md:206`). Сегодня `platform/internal/ingest/notes.go` держит рукописную копию закрытого словаря ЧУЖОЙ зоны: причин движка **16** (испр. 05.09 — шестнадцатой приехала `off_target_lang` → `wrong_language` с минором 0.10.0; прежняя редакция говорила 15 и это ровно то расхождение, которое строка предсказывала) → коды замечаний контракта. Импортировать движок платформе нельзя (D39.85 — разные модули), поэтому расхождение появится молча в тот день, когда движок добавит причину: платформа отдаст `unspecified` и напишет ERROR в лог, то есть деградация честная, но карта протухнет незаметно. ⚠ **Правила заполнения контрактных фраз по этим причинам УЖЕ НАПИСАНЫ** и выводить их заново не надо — компаньон `14-api-contract/README.md`, греп `по ДОККОММЕНТУ` (фраза пишется по доккомменту `disposition.go`, а не по имени константы; класс 2 схлопывается в ОДИН код). Лечение: движок публикует свой словарь причин артефактом-данными (тем же классом, что манифест и сайдкары банка), платформа читает его вместо копии. ⚠ Класс: носителем был ТОЛЬКО регистр платформы (PD-246) — обязательство к ЧУЖОЙ зоне жило внутри зоны автора | бэкенд | когда-нибудь (со следующим касанием эмиссии флагов) | отдельное решение | приёмка P7 (D39.153), релей §7(в) | -| 207 | **Пол самосогласованности манифеста стоит только у материализатора, интейк тот же документ ПРИНИМАЕТ — и по такой книге можно ОПЛАТИТЬ прогон** (`PD-367`, вторая волна ревью P8-FIX). Манифест `{ChaptersTotal: 120, UnitsTotal: 400}` с пустым списком глав `Whole()` отвергает, а `books.Parse` заводит книгу `not_started` с `chapter_count=120` и пустым деревом; потолок считается ОТ `chapter_count`. **Очевидное лекарство опровергнуто исполнением самой зоной:** применить `Whole()` на интейке нельзя — вся батарея интейка ездит на манифестах без списка глав, контракт интейка это только счётчики. Значит решение не зонное: либо контракт интейка меняется, либо пол ставится в другом месте цепи | оркестратор → платформа | скоро | нужно решение (лекарство ломает запиненный контракт интейка) | D39.154 п.10, `PD-367` | -| 209 | **Риг живых проб не может залогировать тела запросов ни при каких env** (находка бэкенд-пака честности 17.08, оставшаяся без носителя до аудита доков 22.08): `LOG_LLM_BODIES=1`+`LOG_LEVEL=debug` объявлены носителем тел, но ключ читается из `obs.ReqInfo` контекста, а `live_reprobe_test.go` строит ctx БЕЗ `WithReqInfo` — гейт `obs/logging.go` не пропускает. Обход, которым пользовались: ручной дамп сообщений в файл. Цена — каждая живая проба, которой нужно прочитать провод глазами, платит за обход заново | бэкенд | когда-нибудь (следующее касание рига живых проб) | малое касание (`WithReqInfo` в риге) + пин | пак честности 17.08, вынесено аудитом доков 22.08 | -| 213 | **ОСТАТОК — одна строка в ДЕВ-пути: супервизор зашивает `"book.yaml"` мимо константы `ConfigFile`** (`platform/internal/ingest/supervisor.go:142`=`"status", "--config"`). ⚠ **ГЛАВНАЯ половина ЗАКРЫТА лендингом P9 (D39.162):** путь банк-экспорта берётся из конверта артефактов движка (`platform/internal/runner/artifacts.go:28-35`; пустой путь — ГРОМКИЙ отказ), нестрогий парс `book.yaml` и собственный `projectDB()` снесены. Осталась ровно та тривиальность, которую строка называла рядом с дефектом. ⚠ Пере-именование банк-экспорта в фикс-имя рядом с `events.jsonl` — ЛОМАЮЩЕЕ, его место в окне строки **161**, НЕ здесь | платформа | когда-нибудь (одна строка, следующим касанием зоны) | правка дев-супервизора | консилиум шва 22.08; главная половина — D39.162 | -| 214 | **Подпись банка не оставляет на банке НИ ОДНОГО следа.** Единственная долговечная запись акта подписи — булев `bank_released` на прогоне (`platform/internal/pgstore/runs.go`, греп `bank_released` (номер строки двигает живая сессия зоны)): кто и когда подписал, что именно вошло в подписанный набор — не хранится нигде. Следствие: пост-фактум ответить «почему в книге этот перевод термина» нельзя, а при пере-нарезке или пере-прогоне восстановить намерение человека не из чего. ⚠ **ЧАСТИЧНЫЙ ответ появился с дверью правок (D39.162):** её документы решений — долговечная запись того, ЧТО владелец решил, и они переживают прогон. Не отвечено по-прежнему: КТО и КОГДА подписал, и что именно вошло в подписанный набор. Всплыло трассировкой цепи банка 22.08, подтверждено пере-проверкой | платформа + бэкенд | когда-нибудь (с трубой доставки правок, D39.156) | отдельное решение о провенансе подписи | трассировка цепи банка 22.08, пере-проверено №19 | -| 227 | **`signature` в квитанции двери правок считается от карты, которую переписывает ЛЮБАЯ граница майнинга** (находка воркфлоу-ревью P9, 28.08): запись карты стоит ВЫШЕ решения о стопе (`backend/internal/pipeline/mining.go:192`=`writeFileAtomic(r.signatureMapPath()`), поэтому `signature != null` НЕ означает состоявшегося стопа подписи; `surfaces`/`undecided` дрейфуют между двумя вызовами владельца, а `undecided: 0` достижим при НЕпредъявленных решениях (кап top-200 вытесняет). ⚠ Починка аддитивна и носитель для неё уже есть: карта несёт СВОЙ идентификатор (`backend/internal/membank/decisions.go:981`=`id, err := seed.SignatureMapID(content)`), а шов его не читает — отдать идентификатор в квитанцию и судить по нему. Цена сегодня мала (поле информационное, гейтом не служит) и растёт вместе с экраном подписи: именно он будет решать «что я подписываю» по этому числу | бэкенд | когда-нибудь (гейт: заказ экрана подписи) | аддитивная правка квитанции | воркфлоу-ревью P9, D39.162 | -| 228 | **Отклонённая поверхность возвращается АЛИАСОМ уцелевшей строки — движок не держит того, что канон уже обещает** (находка воркфлоу-ревью P9 в форме Д1, УЗКО пере-сформулирована бэкенд-сессией 28.08 и принята приёмкой): канон говорит дословно «declining a surface removes EVERY window of that surface» (`docs/architecture/14-api-contract/openapi.yaml:2344`=`declining a surface removes EVERY window`; адрес пере-нацелен 02.09 — минор 0.9.0 сдвинул прежний 2051), а эмиссия майнера энтити-широка (`backend/internal/pipeline/miner_emit.go`, `clusterTouches`), тогда как фильтр авто-банка ключуется только по собственному `src` строки (`backend/internal/pipeline/mining.go:179`=`NormalizeSourceKey(m.Src)`). ⚠ **Правильная форма — снять АЛИАС со строки, а не снести строку:** расширение `decline` до энтити противоречило бы ратифицированному контракту, и именно поэтому бэкенд-сессия применила право §9 и НЕ чинила это попутно. Предмет — банковая онтология (`18-bank-ontology.md`), не тихая порча | бэкенд | скоро (гейт: заказ по читающей стороне банка) | отдельный заказ узкой формы | воркфлоу-ревью P9; форма — бэкенд-сессия 28.08, D39.164 | -| 229 | **Снапшот не фолдит модель ВНУТРЕННИХ гейтов — флип провода под неизменным `request_hash`** (самонаходка бэкенд-сессии 28.08, подтверждена приёмкой): снапшот фолдит `Capability` СТАДИЙНЫХ моделей и их эскалации (`backend/internal/pipeline/snapshot.go:316-340`), но модель `gates.terminology.model` / `gates.repair.model` (`backend/internal/config/internal_call.go:72`) не фолдится сознательно — а терминолог шлёт ДВА системных сообщения, так что смена оси `capabilities.system_messages` у провайдера, которым пользуется только гейт, меняет байты запроса при неизменном хеше: тихий false-hit класса D5.2. ⚠ **Сегодня ЛАТЕНТНА и денег не стоит — проверено приёмкой: гейта `terminology` нет НИ В ОДНОМ конфиге репозитория** (`grep -c terminology configs/pipeline-c1.yaml` = 0). Триггер починки — день, когда гейт включат с провайдером, объявляющим НЕдефолтную возможность. ⚠ Цена лечения — денежная: фолд гейт-моделей сдвигает хеши и обесценивает чекпойнты; дешёвая форма — фолдить ТОЛЬКО недефолтное (приём `omitempty`, прецедент `MinMaxTokens`), тогда сегодняшние снапшоты остаются байт-равными | бэкенд | когда-нибудь (гейт: включение внутреннего гейта либо следующее касание снапшот-контракта) | правка снапшот-контракта | самонаходка бэкенд-сессии, D39.164 | -| 230 | **Инертный `decline` подписанного сид-терма отвечает `already_applied` вместо единственной работающей инструкции** (названный размен пака «тихая порча», D39.164): сузив отказ по поверхности ради СХОДИМОСТИ повтора, движок потерял поучение в одном углу — когда отказ и записан, и по-прежнему инертен против `glossary_seed`, пользователь получает «уже применено» вместо «убери терм из сида». Сходимость сочтена более тяжёлой обязанностью (на ней стоит вся раскладка класса 15 и синхронная дверь платформы), но размен РЕАЛЕН. **Форма закрытия — поле отчёта со стоячим фактом**, то есть аддитивная правка формы шва: платформенный `BankReport` — аллоулист, лишнее поле на провод не уедет само | бэкенд + контракт | скоро (с ближайшим касанием отчёта двери) | аддитивное поле отчёта | размен пака «тихая порча», D39.164 | -| 232 | ⚠ **ЛИД ПРОТУХ — испр. 05.09: вторая половина (слот гранта на прерванном между волнами юните) ЗАКРЫТА** паком «число согласия» (`D39.187`, пин `TestAUnitInterruptedBetweenWavesTakesNoSecondSlot`; эррата 03.09-а). **Настоящий остаток** — две схемные оси («первая редакторская стадия», «прерванная пере-делка») и отложенное слово владельца о семантике переноса. **Ось «свежий/пере-делка» выведена из ПОЛНОТЫ СТРОК, а не из факта отгрузки** (D39.170, находки охотника 3 и 4). Следствия ДЕНЕЖНЫЕ на слух покупателя: добавление стадии в пайплайн превращает ДОЧИТАННУЮ книгу в «3 unit(s) NEVER delivered» и приглашает купить её снова; юнит, прерванный между волнами (signature stop, денежный потолок, Ctrl-C), второй раз считается свежим и тратит слот гранта повторно — замерено 4 купленных юнита → 2 главы. Носитель у движка УЖЕ есть: реестр анонсов `events_outbox.once_key` (`backend/internal/pipeline/events.go:401`=`unitOnceKey is the identity of one announcement`), ключ `unit:<книга>:<волна>:<глава>:<юнит>`, монотонный на всю жизнь книги и переживающий и добавление стадии, и обрыв между волнами. ⚠ **ПЕРВАЯ ПОЛОВИНА ИСПОЛНЕНА 31.08** (`bb541a8`, экземпляр A11; испр. 02.09): читающий метод `store.AnnouncedOnceKeys()` построен, его докстринг называет эту строку по номеру, предикат — `delivered[key] && unitShipped(rows)`. **ЖИВОЙ ОСТАТОК — ВТОРАЯ ПОЛОВИНА:** юнит, прерванный МЕЖДУ ВОЛНАМИ, повторно тратит слот гранта (разбор — `backend/docs/MONEY_HONESTY_REPORT.md` §4.5). ⚠ РАЗВИЛКА, которую надо назвать в промте: ключ несёт ВОЛНУ, значит «юнит отгружен» — факт per-wave. **Ответ есть и он не новый механизм:** отгрузкой считается волна, владеющая ОТГРУЖАЮЩЕЙ (последней) стадией — `backend/internal/pipeline/snapshot.go:243`=`finalStageWave is the wave that owns the SHIPPING (last) stage`; на редакторском конвейере это edit, на черновом-только — draft. Проверять надо ИМ, иначе черновой-только конвейер получит ось, которая никогда ничего не считает отгруженным (предложено движковой сессией при сдаче, сверено мной по коду) | бэкенд | скоро | Читающий метод стора + перевод оси на факт отгрузки; отдельный пак | приёмка D39.170 | -| 233 | **Трата терминолога вне объёмного потолка масштабируется КНИГОЙ, а не грантом** (D39.170). Замер: три последовательные покупки по одному юниту на четырёхглавной книге дали три полнокнижных консолидации по $0.005460 каждая — покупка одного юнита обходится в ~1.5× стоимости самого юнита. Книга на 500 юнитов, проданная по одному, оплатит 500 полнокнижных проходов. Место траты — в ЦЕНЕ, а не в потолке (решение подтверждено), но при мелкой нарезке продажи она перестаёт быть накладной и становится основной статьёй: это ВХОД В КАЛИБРОВКУ ЦЕНЫ, а не сноска | бэкенд | скоро | Учесть в модели цены при следующей калибровке; либо чекпойнт консолидации, переживающий покупку | приёмка D39.170 | -| 237 | **Два загейченных триггера НАЖАТЫ и не отработаны** (реестр `13-tech-debt-anchors.md` §Б-108, сверено 30.08). **(а) `go.work`:** условие «появление Go-кода платформы» выполнено давно — `platform/go.mod` есть, `ls go.work` в корне даёт «No such file or directory». Ратифицировано D39.85 §8 п.4 (`docs/research/23-engine-platform-seam.md:66` = `go.work — коммитить, когда у платформы появится Go-код`); цена — один файл, по тому же §6 он решает только dev-удобство и не меняет ни видимости, ни версий. **(б) вендор-сверка маппинга эффорта `deepseek-v4-pro`:** вахта D39.92 сработала 13.08 changelog'ом вендора. ⚠ **Испр. 05.09: НОСИТЕЛИ БОЛЬШЕ НЕ ПРОТИВОРЕЧАТ** — и квирки (`docs/experiments/00-provider-quirks.md` §3г), и `STACK.md` говорят одно: ручка ДОХОДИТ до модели. Прежняя редакция обвиняла оба носителя в утверждении «ручки у pro НЕТ», которого ни один из них уже не несёт, и это заставляло сессию искать спор, которого нет. Живой остаток — вендор-сверка САМОГО МАППИНГА и величина эффекта, и по гардрейлу владельца это закрывается ТОЛЬКО вендор-докой, а не выбором стороны. Держит жильца Д5 и калибровку цены редакторского арма. ⚠ **Класс важнее двух пунктов: спроектированный механизм без носителя события тихо становится долгом, и никто не проверяет, не нажат ли спусковой крючок.** | оркестратор | скоро | (а) один файл в корень; (б) заказ полигону на вендор-сверку | аудит очереди 30.08 | -| 241 | **Канон противоречит сам себе на ДОЧИТАННОЙ книге, и принятая правка банка умирает молча** (названо телом D39.165 §3 28.08, носителя не получило; заведено оркестратором №20 30.08 по находке сессии P12). Две фразы: правка банка «takes effect on the NEXT run» (`docs/architecture/14-api-contract/openapi.yaml:511`=`takes effect on the NEXT run`) против «finished work is not bought twice» + подъём потолка только у ПРИОСТАНОВЛЕННОЙ книги (`:590`=`finished work is not bought twice`). У дочитанной книги следующего прогона купить нечем: пользователь правит банк, получает квитанцию об успехе — и правка не доезжает ни до одной строки никогда. ⚠ Смежное лечение уже существует и не связано с этой дырой: пере-проход ПОКУПАЕТСЯ членом `RunRequest.re_pass` (канон 0.7.0, D39.166) — то есть механизм есть, а фраза канона его не признаёт для дочитанной книги. Решать формой: либо канон признаёт пере-проход входом для дочитанной книги, либо дверь правок отказывает такой книге ЧЕСТНО вместо ложной квитанции | контракт (+платформа) | скоро (следующее касание контракта) | контрактный минор + пин на дочитанной книге | D39.165 §3, эррата 30.08-б, находка сессии P12 | -| 242 | **Реестр D-нот: колонки «статус» и «тело» разъехались на 74 строках из 224** (замер аудита доков 30.08). У свежих нот в «статусе» стоит заметка «ЖИВОЕ: …», а слово `жив` уехало в «тело»; шапка таблицы описывает другой порядок. Гейт `counts.py --check` этот класс НЕ ловит по устройству (сверяет полноту номеров, не форму ячеек). Лечение — не ручная перекладка (дороже пользы и легко внести новую ложь), а машинное: правило формы в `counts.py` + разовый прогон приведения. Пока не сделано — в легенде реестра стоит правило чтения (испр. 30.08) | оркестратор | когда-нибудь | правило в `counts.py` + разовое приведение | аудит доков 30.08 | -| 243 | **Остаток аудита доков 30–31.08: 19 удержанных находок НЕ применены** (аудит — 5 линз + верификатор на каждую, 57 находок, 55 удержаны, 36 применены сменой №20). Перечень: ~~**arch-3**~~ **ЗАКРЫТ 31.08 — разбор телом D39.179 п.5** (был вдвое больше заявленного: 51 указатель вместо 13, и дороже адресов оказались ЛОЖНЫЕ КЛЕЙМЫ) · **arch-5** (правило языка знает две корзины, `reader.txt` — третья) · **arch-7** (§2 закона шва: дисциплина флока не описывает новый глагол-писатель) · **arch-9** (реестр загейченных триггеров не знает нажатых 30.08) · ~~**arch-10**~~ и ~~**arch-11**~~ **ЗАКРЫТЫ 02.09** (числа словаря событий сняты в пользу кода; отвергнутый ключ назван отвергнутым) · **arch-12** (шапка `09-target` сама зовёт себя неполной — строку под таблицей слоёв надо внести; ⚠ ЖИВ на 02.09: греп `D39.181` по `docs/architecture/09-target-architecture.md` — 0 хитов, греп `D39.182` — 0 хитов, то есть лендинги 31.08 в док слоёв не внесены) · **contract-8** (эррата 15.08-в в шапке D-лога указывает на промт, уехавший в архив) · **contract-10** (`Export.failure_code` «becomes an enum with the first built format» — формат построен, условие наступило) · **progress-6/7/8/10/11/12/13/14/15** (мелочь CURRENT-STATE и строк бэклога: протухшие «запушена»/«строка 200»/якорь `miner_emit.go`/дубль 238 внутри 160 и пр.). ⚠ Отчёт аудита жил в песочнице сессии №20 и умирает с ней — здесь ЕДИНСТВЕННЫЙ носитель списка; воспроизведение = повторный аудит (5 агентов, ~2 часа) | оркестратор | скоро | пройти списком | аудит доков 30–31.08, сдача смены №20 | -| 244 | **Гейт якорей на пре-коммите ломается всякий раз, когда зона правит КОД и СВОЙ реестр одним незакоммиченным деревом** — и врёт в обе стороны. Механика: хук судит ЗАКОММИЧЕННЫЙ док против РАБОЧЕГО кода, поэтому пере-нацеленные, но не залёнджённые якоря читаются как битые. Замерено на приёмке P12 31.08: у оркестратора хук напечатал 13 битых якорей `platform/docs/DEFECT_REGISTER.md`, у зоны `counts.py --lint` на том же дереве дал **0**; права зона — в HEAD `internal/runs/runs.go:323`, в рабочем `:347`, и токен по новому адресу на месте. ⚠ Обратная сторона опаснее и не замерена: якорь, ставший битым ПО-НАСТОЯЩЕМУ, тем же механизмом может оказаться зелёным. Свойство общее, не про этот пак | оркестратор | когда-нибудь | либо судить обе стороны из одного состояния (`--from-index` уже есть — проверить, покрывает ли он случай), либо печатать, что сравниваются РАЗНЫЕ состояния | приёмка P12 оркестратором №21, 31.08, разрешено командой | -| 245 | **Pathspec-форма коммита молча роняет UNTRACKED-файлы, и сломанный коммит выглядит нормальным до первого чужого прогона.** `git commit -- <пути>` обходит ИНДЕКС и берёт рабочее дерево только для ОТСЛЕЖИВАЕМЫХ путей: предварительный `git add` нового файла она игнорирует. Поймано на лендинге P12 31.08 — коммит `e1cb692` унёс `migrations.sha256`, уже ссылавшийся на три миграции, а сами миграции 00029/00030/00031 и три теста остались снаружи; починено амендом секундного неопубликованного коммита при пустом индексе (`0a680a3`). ⚠ Канон git-координации в `CLAUDE.md` объясняет про pathspec ТОЛЬКО то, что она не трогает чужой индекс — то есть учит половине правды и ровно этим создаёт ловушку. Норма, которую предлагаю вписать: новые файлы стейджить явно и проверять состав `git show --name-only`, а не доверять форме. ⚠ **ПОЛОВИНА ПОСТРОЕНА 31.08** (`94381bb`, испр. 02.09): в `docs/scripts/githooks/pre-commit` стоит warn-блок, который перед каждым коммитом печатает неотслеживаемые файлы в каталогах коммита. Живой остаток — блок ПРЕДУПРЕЖДАЕТ, но не блокирует, и на свежем клоне хук вообще не установлен (строка 220) | оркестратор | скоро (решение владельца — его канон) | одна строка в `CLAUDE.md` §«Git-координация мультисессий»; вписывает владелец или оркестратор по его слову | лендинг P12 оркестратором №21, 31.08 | -| 247 | **§2.2 закона раскрытия опровергает себя следующей же строкой — эррата зонного дока.** Формальная фраза требует «держит ОБА операнда сравнения и обязано их НАПЕЧАТАТЬ», а её собственный пример тут же говорит обратное: честная форма — НАЗВАТЬ ОСЬ («снапшот разошёлся» честно, «конфиг/промпты изменились» ложно). ⚠ **Ратифицированный текст D39.181 п.1 требования «напечатать» НЕ СОДЕРЖИТ ВОВСЕ** — оно живёт только в `backend/docs/DISCLOSURE_LAW_DESIGN.md`, значит противоречия с ратификацией нет и решает ЗОНА, не владелец. ⚠ Довод «граница прячет имена моделей и хеши» ОПРОВЕРГНУТ исполнением: эти значения уже едут по тому же stderr штатным INFO-логом, включая `memory_version=<12 hex>` — значение того самого поля. Цена бездействия на живых данных = НОЛЬ (единственная сдвинувшаяся ось — хешевая, печать дала бы две несравнимые строки SHA) | бэкенд | когда-нибудь | эррата к §2.2: операнды называются осью, а не значением | приёмка D39.182 + разведка оркестратора 31.08 | -| 248 | **Полнота самообъявления о правках чужих тестов ничем не проверяется — и трижды оказалась неполной.** P11 назвала файл, которого не трогала; P12 не назвала тест, у которого переписаны ОБА утверждения; сессия пака «деньги и честность» в первой редакции комментария утверждала неверное о силе собственной правки. ⚠ **Мой метод проверки был слабее, чем я его подал:** греп `^[-+].*t\.(Error|Fatal)` ловит строку СООБЩЕНИЯ, а утверждение — это строка СРАВНЕНИЯ, и она другая (замер: греп локализует утверждение в 1 случае из 475). Предложение разведки: warn-only гейт-детектор при лендинге — список пред-существующих тестов с изменёнными строками утвержденческой формы ВНУТРИ пред-существующих тел; прототип ~25 строк sh прогнан на двух лендингах и указал ровно на `bankfixpack_test.go`. Площадка есть — `docs/scripts/githooks/pre-commit` уже warn-only. ⚠ Ложняки измерены: целиком новый `t.Run` внутри старого `func` даёт срабатывание (1 из 6 на P12) | оркестратор | скоро | гейт-детектор warn-only + пункт чек-листа приёмки | разведка оркестратора 31.08 по вопросу владельца | -| 249 | ⚠ *(пример в теле ниже ссылается на ряд PD-246 — он ЗАКРЫТ D39.194; пример держим как археологию класса, живым рядом его не читать)* **Девять рядов бэклога потеряли слово веса, и гейт на них НЕ краснеет.** ⚠ **Лечение ПОСТРОЕНО (сверено кодом 02.09): вес судится ПРЕФИКСОМ ячейки** — `docs/scripts/counts.py`, греп `BACKLOG_WEIGHTS` (три слова: «блокер-очереди» · «скоро» · «когда-нибудь»), и «скоро» считается тем же префиксом. Этим убита ВТОРАЯ половина класса: подстрока ловила слово в ПРОЗЕ, и фраза «переведена из «скоро»» ре-добавляла ряд в счёт — число скакнуло **53 → 56** при одной новой строке (замер 02.09, пере-счёт скриптом). ⚠ Гейт рождён ЗЕЛЁНЫМ, а не красным: девять известных рядов внесены «дедовщиной» — греп `WEIGHT_GRANDFATHERED` там же, ряды **5 · 13б · 94 · 96 · 97 · 149 · 205 · 221 · 246**. **ЖИВОЙ ОСТАТОК — сами ячейки:** у 96/97 прочерк ЗАКОНЕН (надгробия строк, уехавших в зонный бэклог, D39.84), остальные семь потеряли вес молча и чинятся оркестратором — каждая починенная выходит из списка дедовщины. ⚠ Два ряда шире класса: **149** («исполнен и заленден 10.08») и **205** («сделано 21.08») объявляют себя ИСПОЛНЕННЫМИ прямо в колонке веса, хотя по правилу таблицы закрытые строки в ней не живут — это либо живой остаток без веса, либо непойманный класс C; **246** несёт самодельное «СРОЧНО», которого в словаре нет. | оркестратор | скоро ($0, гигиена трекера) | правка семи ячеек → выход из `WEIGHT_GRANDFATHERED` | ревизия доков 02.09, приёмка контролёра | -| 217 | ⚠ **ЛИД ПРЕУВЕЛИЧЕН — испр. 05.09:** «не работают вовсе / блокирует любой прогон» ложно — пользователь `ubuntu`, литерал пути РАЗРЕШАЕТСЯ, полигон покупал 30.08–02.09. Живой долг — сам захардкоженный путь, а не блокировка. **Скрипты полигона захардкодили АБСОЛЮТНЫЕ пути двух корней и не работают на этой машине вовсе.** ДВА РАЗНЫХ слома. **Корень репо** — смена пользователя: литерал в 121 файле, из них 104 дословно `REPO = Path("/home/ubuntu/projects/textmachine")`, портабельных форм всего 5. **Корень книг** — оба события порознь: литерал `/home/ubuntu/books` 86 файлов (пользователь), портабельный `Path.home()/"books"` 89 файлов (переезд каталога; на прежних машинах работал). Объединение 173 файла. Пользователь теперь `ubuntu-26`, книги переехали в `<репозиторий>/books` ⇒ ломается и то и другое, включая ЖИВОЙ гейт фазы Д `eval/conformance.py:49`=`REPO = Path("/home/ubuntu/projects/textmachine")`. Живых носителей 26 по корню книг (среди них портабельная форма преобладает 20:6) плюс корневые гейты и сборщики корпусов; остальное — скрипты закрытых эксп-12–16, их владелец велел ВЫБРОСИТЬ, а не чинить (D39.157 п.4а). Форма правки — за зоной; приор оркестратора: один модуль путей, корень резолвится МАРКЕРОМ вверх по дереву (движок так и делает — `backend/internal/miner/miner_parity_test.go:29`=`derived from the repository MARKER`), книги от него, обе ручки перекрываются env | полигон | скоро (блокирует любой прогон зоны) | пак путей полигона | переезд машины 24.08, №19 | -| 219 | **Line-якоря в тела D-лога обречены съезжать, и механизм именно в дисциплине эррат.** Эрраты вписываются в КАРТУ ШАПКИ (append-only, D23.3), то есть в начало файла, — значит каждая эррата сдвигает номера строк ВСЕХ тел ниже, и любой якорь вида `05-decisions-log.md:NNN` умирает молча. ⚠ Замерено на себе 27.08: три эрраты за сессию убили якоря в `docs/architecture/17-seam-inbound-law.md` (греп `Эррата, которую ратифицирующая нота обязана поставить`) и `docs/research/25-seam-cold-review.md:5`=`адресуем НОМЕРОМ, а не строкой` (оба целили в `:232`, тело уехало на `:239`; ⚠ 02.09 обе площадки уже переведены на форму номера ноты — прежний голый указатель `17-seam-inbound-law.md:120` показывает пустую строку). Лечение — не пере-нацеливание (оно повторится через эррату), а СМЕНА ФОРМЫ якоря: в тела D-лога целиться номером ноты (`^## D39.106`), который стабилен навсегда, а не строкой. ⚠ **Первая половина лекарства ПОСТРОЕНА:** `counts.py --lint` сверяет якоря в тела D-лога СТРУКТУРНО и без токена — владелец целевой строки (ближайший `^## D<номер>`) обязан совпасть с номером, названным рядом; остаётся перевести живые якоря на форму номера | оркестратор | скоро (растёт с каждой эрратой) | `--lint` учит форму `файл:^## D<номер>`, живые якоря в D-лог переводятся на неё | ревью доков 24.08, механизм и отсутствие носителя — 27.08, D39.160 | -| 220 | **Репо-широкий гейт доков бутстрапится пакетным менеджером ОДНОЙ зоны, и та заморожена.** Диспетчер `.git/hooks/pre-commit` зоно-нейтрален по построению (`for hook in */scripts/githooks/pre-commit`, `#!/bin/sh`, node не нужен) и судит `CLAUDE.md` + `docs/**` + `platform/docs/**` + `frontend/docs/**` (`docs/scripts/counts.py:566`=`ROOT / "CLAUDE.md"`), но единственный его УСТАНОВЩИК — `frontend/scripts/githooks/install.mjs`, вызываемый ключом `prepare` из `frontend/package.json`. Охват и бутстрап не совпадают ⇒ инструмент решает свою задачу не в полной мере. Проверено исполнением 24.08: на этой машине `.git/hooks/` содержал только `*.sample`, гейт МОЛЧАЛ, ничего не проверив, и поймал первые четыре дефекта только после ручной установки; сессия бэкенда или доков `npm install` не делает никогда. Приор: зоно-нейтральный установщик в `docs/scripts/githooks/` как ЕДИНСТВЕННЫЙ писатель диспетчера, `prepare` фронта зовёт его — фронтовая половина выписана пингом №19 в зонный журнал фронта. ⚠ Ручная установка — временная мера, пока строка открыта; записывать её как порядок работы ЗАПРЕЩЕНО (это ровно тот обход, цену которого называет шапка `CLAUDE.md`) | доки + фронт | скоро | зоно-нейтральный бутстрап + правка `prepare` при разморозке | аудит переезда 24.08, №19 | -| 49 | **Этапы Б+В спеки D15.2** (content-addressed resume / `guard_hash` — D39.31 сознательно не строил) ; этап В = tmctl export-контракт D29.1 (annot-v1 · цвет-мап+rollup · политика красных fail-closed) + операторский протокол-документ релиза гендер-твиста (D5.1): сам механизм УЖЕ построен — until_ch-правка → точечный re-edit со сметой и $0-пере-пином (`repin.go`/`rebill.go`, D39.42 п.5/D39.45) | бэкенд | скоро (ПОДТЯНУТА D39.81: annot-v1 = источник замечаний для фронта — критический путь подключения) | отдельное решение (annot-половина — по контракту 14, D39.99) | D39.34(4), D33 п.5, D39.81 | -| 49а | **ALTER-шаги миграций v8–v14 не идемпотентны вопреки шапке `migrate.go:9-11`** (полу-применённая БД не сходится; счётчик версий скрывает) — находка критика полноты пака-19 | бэкенд | когда-нибудь | отдельное решение | D39.56, PACK19_BUILD §6.9 | -| 50 | F3-остаток идемпотентности | бэкенд | когда-нибудь | отдельное решение | D39.34(4) | -| 51 | `human_override` LOCK (D29 п.1г, в коде 0 вхождений) | бэкенд | когда-нибудь | отдельное решение | D39.34(4) | -| 52 | **Ф2-гейты вне идеала**: морфо-гейты канцелярита + L1-лемматизация (python-сайдкар) · полный OpenCC · опциональный пре-перевод гейт ; состав явно: канцелярит + РОД (строка 82) + класс Ф2-гейтов карты 04-unhappy (обсцен-гейт/феминитивы/время сцены — состав решить паком) ; + класс идиоматики (свип-хвост, D39.73): сехоуюй-словарь · вэньянь-классификатор (zh) · васэй-эйго ложные друзья (к ja-паку 81) — данные пары или закрытие «банк книги покрывает» тем же паком | бэкенд | когда-нибудь | отдельное решение | D39.34(4) | -| 54 | Масштаб целой книги: волны/каденс/потолки/ETA на сотнях глав (гоняли максимум 10; книга 7,78 млн симв., ~2284 раздела). ⚠ **Дописка инвентаря №18 (D39.147 п.2г):** жёстких потолков размера в коде НЕТ, но исходник читается в память целиком (`chunk/ingest.go:98`), чтения стора беспагинационны под `opTimeout = 10s` (`store/store.go:39`) и бюджеты нарезки калиброваны на 25 главах (`config/pipeline.go:126-138`) — ни одно из трёх на 2283 главах не проверено ничем | бэкенд | когда-нибудь (последним по курсу) | МАСШТАБ | D39.33, CURRENT-STATE | -| **— ПОЛИГОН (кандидаты пакетов) —** | | | | | | -| 55 | **`dialogue_dash` мерить только на невиданном тексте** (подогнан под 蛊真人; цифры мини-прогона аргументом не считаются) ; расширено до вне-претрейн чекпоинта целиком: r-коэффициенты exp01/08 · precision чекеров · частота эха · чистовик exp15-выводов ; + arity-полоса паспорта (D29.2г): решить — dialogue_dash покрывает диалоговую половину или мерить (D39.73). **Частично закрыта эксп-21 (D39.117):** направление главного вывода воспроизведено на чистом en-материале (узнавание 1/5), $0-довесок исполнен частично; ⚠ **ПЕРЕ-СНЯТА 05.09 (D39.198 п.5): требования НОВОЙ книги здесь НЕТ.** Владелец: прогоняем на тех же текстах (мастер Гу и Жан-Кристоф), а «известность модели по претрейну» остаётся ОГРАНИЧЕНИЕМ ВЫВОДА — результат на классике читается как предварительный, и это пишется в вывод, а не покупается новой книгой. Прежняя редакция несла ЖЁСТКИЙ платный заказ полигону. **срез эксп-21 НЕ купил** (главный zh-замер на книге 4/5, без пинга) — остаток = **ОГОВОРКА В ВЫВОДЕ**, а не покупка: замер идёт на мастере Гу и Жан-Кристофе, а «модель знает текст по претрейну» пишется ограничением результата (⚠ испр. 05.09 — колонки продолжали заказывать неконтаминированный zh-срез уже ПОСЛЕ того, как шапка строки его сняла: полигон читает колонки) | полигон | когда-нибудь (оговорка вывода, не заказ) | формулировка в отчёте | D39.37(4), D39.40, D39.46, D39.108, **D39.117** | -| 56 | Ёфикатор/санитайзер-классы не размечены (§6.5 отчёта пакета-6) | полигон | когда-нибудь | полигон-пакет | D39.46, CURRENT-STATE | -| 57 | Пере-замер «контексты — главный рычаг» на трудной выборке пакета-7 с боевой сборкой (до него kwic-веса/семантику не трогать; перф-хвост AttachKWIC — строка 37: фикс-пак 128 закрыт D39.118, опция в нём не взята, семантика не менялась) — напряжение с D39.46 названо, не отменено | полигон | когда-нибудь | полигон-пакет | D39.50, D39.118 | -| 58 | **Не покрыто пакетом-8**: вторая книга/пара/модель · строка `drafts:` · ось `batch_runes` · разметчики-модели (не люди) · precision роли на «расширенном, но осмысленном» материале ; + контрастивный регрессионный сьют по каталогам режимов отказа (12-*) · чистовик exp15-выводов | полигон | когда-нибудь | полигон-пакет | POLYGON_PREMEASURE §1.8/§2.5/§3.5/§7.6 | -| 59 | **Вендор-чек префикс-кэша ZAI/GLM** (на нём стоит вся кэш-экономика W1/Q2c) ; + GLM context-overflow гард (finish=model_context_window_exceeded — NOT-do пака-12 без решения) ; + Mistral-strip гейт message-builder (research/21 §1.1: extra_forbidden на reasoning-поля; ЛАТЕНТЕН при нашем single-shot wire — гейт перед прод-путём mistral в канале B / любым multi-turn; D39.74) | полигон | когда-нибудь (до МАСШТАБА) | полигон-пакет | D39.34(6) | -| 60 | Scheduler-aware волны под peak-valley DeepSeek (прямой COGS-рычаг) | полигон/бэкенд | когда-нибудь (до МАСШТАБА) | отдельное решение | D39.34(6) | -| 61 | **Прайс/wire-гигиена**: продление `prices_checked` без правки чисел · гейтнутые платные армы (edit-единица >3200 и др.) · wire-probe temperature в thinking-канале DeepSeek | полигон | когда-нибудь | полигон-пакет | D39.34(6) | -| **— Ф2.5 / ПИЛОТ / ПРОД —** | | | | | | -| 62 | Билингв-якорь (D25 п.9 Q1) | владелец | когда-нибудь | Ф2.5 | D25 п.9, CURRENT-STATE | -| 63 | Контаминация корпуса (D27 п.4) | владелец/полигон | когда-нибудь | Ф2.5 | D27 п.4, CURRENT-STATE | -| 64 | Судья-дублёр (D22.6) | бэкенд | когда-нибудь | Ф2.5 | D22.6, CURRENT-STATE | -| 66 | Пилотные D25-гейты: publishable/waiver (п.1) · FN-bound L3 (п.4) | владелец | когда-нибудь | Ф2.5 | D25, CURRENT-STATE | -| 67 | **Прод-гигиена: юр-пакет · провенанс 12-*-доков · xAI-ключ off перед продом** (D27) ; + юрисдикционные annex-ре-чеки при новых рынках (D39.29) + поле «версия исходника» book.yaml на интейке (04-unhappy §5) | владелец | когда-нибудь | Ф2.5 | D27, CURRENT-STATE | -| 68 | Residual-тачпойнты exp16, не влитые в сид-дельту: мини-голд алиасов (ОТЛОЖЕН до первого длинного прогона — D39.103) · precision@30 (`books/gu-zhenren/exp16/`) | полигон | когда-нибудь | Ф2.5 / полигон-пакет | CURRENT-STATE | -| **— Ф3 / ПРОДУКТ —** | | | | | | -| 69 | Gemini API «под-18» обязательство на конечный продукт (независимо от лейблов) | владелец | когда-нибудь | Ф3 / отдельное решение | D39.32, D39.34(7) | -| 70 | Action-security gate перед выдачей tools/webfetch (D25 п.5) | бэкенд | когда-нибудь | Ф3 | D39.34(7) | -| 71 | **Планы research/22**: epub-tag-rewrite · Q7-леджер ; + F3-brief из D29 п.3 (chat-edit · Not-useful-петля · cost-of-fix) + Ф3-скоуп 02-mvp-plan (TMX/TBX · Bertalign · дистилляция 7–14B); + V5: фронт ВЕБ-ПЕРВЫЙ, SEO/ранжирование (куки · страницы-сироты · актуальные алгоритмы Google) — определяет выбор фреймворка (SSR vs SPA), в Ф3-дизайн ДО выбора стека (ПТ-23) | бэкенд | когда-нибудь | Ф3 | D39.34(7), START_PROMT V5, D39.80 | -| 94 | **Продукт-механика входа и прогона** (V2, ПТ-16..18): абьюз/misuse-прескрин дёшево и точно ДО трат токенов (H8) + UI-контракт отказа (проект-решение D39.80) · лимит размера входа настройкой (H7) · продукт-кнопки «стоп/продолжить» поверх построенных graceful stop и redrive, абьюзивный прогон НЕ продолжать (H10); API-форма — по контракту 0.3.0 (отказ прескрина РЕШЁН: `rejected` + грубый `content_refused`, К-9 закрыт D39.138 п.2б) | бэкенд | к подключению фронта (ПОДТЯНУТА D39.81; лимит можно раньше, к пилоту) | отдельный пак при Ф3-препе (контракт 14 ратифицирован) | START_PROMT V2, H7/H8/H10, D39.80, D39.81 | -| 96 | **→ переехала в `platform/BACKLOG.md` П-1** (зонные бэклоги, D39.84: HTTP/SSE-слой, обвязка, аутентификация, порядок деплоя); здесь остаётся ратифицированным сам ИНВАРИАНТ D39.81 — движок = процесс-на-прогон (EXCLUSIVE flock `store.go:43`), сервер в backend НЕ пишется | платформа | — | зонный бэклог | D39.81, D39.84 | -| 97 | **→ переехала в `platform/BACKLOG.md` П-2** (глобальный брокер рейт-лимитов; гейт «до второго параллельного пользователя» зафиксирован там же) | платформа | — | зонный бэклог | D39.81, D39.84 | -| 127 | **Устаревший DDL-коммент `glossary.source`** (`migrate.go:194`: «seed|ruby|auto», фактические пути записи — seed/ruby/mined, `auto` не пишет никто; фантом уже утёк во фронт-доки дважды) — поправить коммент | бэкенд | когда-нибудь (попутно любым паком store) | однострочная правка | ревью контракта 04.08, D39.99 | -| 106 | **Слой 3: целевой контракт «узкие мандаты + ДИФФЫ» против текущего full-regen — гейт «перепроверить до стройки» в силе, приоритет ПОНИЖЕН (D39.117: full-regen выигрывает у ремонта; оговорка полигона — чинил дешёвый фиксер по предложению, не сильный редактор узким мандатом).** Реактивация — только через эту строку. Археология дословно (эмпирика D39.108 · история дыры учёта) — `architecture/13-tech-debt-anchors.md` §Б-106 | владелец → бэкенд | когда-нибудь (пере-проверка «сильный редактор × узкий мандат» — перед стройкой слоя 3) | замер → решение владельца | 09 §Слой 3, D39.90, D39.108, **D39.117** | -| 114 | **Конфиго-слой ручки эффорта: два дешёвых хвоста приёмки (вне снапшота, $0 прогонов).** (а) **Д4 отчёта:** `gates.terminology.target_script` НЕ сверяется с `book.target_lang` — `target_lang: ru` + `target_script: Latin` грузится чисто и **ИНВЕРТИРУЕТ** банковский экран (ловит целевой, пропускает чужой); сверка при загрузке против `lang.LangScripts(TargetLang)` — тот же дата-план, что у экрана строки 46, громкий отказ на несовпадении. (б) **Находка-2 приёмки:** стейл-доккоммент `capability.go:78` — у константы `ReasoningExtraBodyDisable` до сих пор «effort "" leaves the provider default», противореча проводу (`applyToBody` мержит disable на `""`, комментарий в теле arm это прямо объясняет) и починенному `ThinksOnWire`; однострочник тем же касанием | бэкенд | скоро (мелкий пак или попутно со строкой 46) | правка Go, снапшот не двигает | D39.91, EFFORT_HANDLE Д4 | -| 115 | **`//go:embed` целевых данных — ЯВНЫЙ список файлов: новая ЦЕЛЬ требует правки Go (Д6 отчёта).** `internal/lang/embedded.go:22` перечисляет файлы поимённо, `CompileCheckers` паникует при неполном файле цели ⇒ на канон-вопрос «заработает ли пара, которой в репо НЕТ, без правки Go» ответ сегодня **НЕТ** — дыра в ратифицированной «ФАЗЕ 2 ОБЩНОСТИ ✅» (D39.64), и она не про язык, а про строку эмбеда. Решить форму: `embed data/*` (и как манифест фолдится в `EmbeddedVersion`, чтобы НЕ перекупать чужие пары) против явного списка как осознанного гейта полноты данных цели | оркестратор → бэкенд | когда-нибудь (триггер: первая новая целевая пара; учтён в реестре 108) | отдельное решение | D39.91, EFFORT_HANDLE Д6, D39.64 | -| 108 | **Реестр ЗАГЕЙЧЕННЫХ ТРИГГЕРОВ (триггер → что вернётся → источник) — ВЫСЕЛЕН ДОСЛОВНО в `architecture/13-tech-debt-anchors.md` §Б-108; сверять на каждом переходе горизонта (норма D39.66 «каждое отложено получает носитель» в силе).** ⚠ Живое оттуда: go.work-триггер УЖЕ наступил (`platform/go.mod` заведён) — ⚠ **тот же факт несёт строка 237(а), испр. 05.09: чинится ОДИН раз и там, здесь он ЗАПИСЬ РЕЕСТРА, а не заказ** · вахта маппинга эффорта dspro «early August 2026» · движение тулчейна к go1.27 ⇒ строка 119 ПЕРВОЙ | оркестратор | скоро ($0, гигиена трекера) | завести реестр + сверку в норму лендинга | D39.66, D39.90 | -| 109 | **Продуктовые требования без строки-носителя: ПТ-6 (структура абзацев) · ПТ-7 (слабый оригинал — вопрос владельца) · ПТ-22 (продуктовый интейк настроек) · ПТ-10 (механизм веб-фетча).** Носители заводить при первом касании тем; реестр `product-requirements.md` первичен. Разбор дословно — `architecture/13-tech-debt-anchors.md` §Б-109 | оркестратор/владелец | скоро ($0 — расписать носители) | завести строки/вопросы → диспозиции | D39.90, product-requirements | -| 110 | **Детектор повторов лемм / защита авторских рефренов** (`04-unhappy-paths.md:97,130 п.5`): $0-минимум исполнен промптом (editor.md, пакет-чекеров 02.08), механизм явно не строился — «нет размеченного класса; связка с alignment/Bertalign». Строки-носителя не было; предмет живой, потому что отличить дефектный повтор от авторского рефрена без выравнивания нельзя | бэкенд/полигон | когда-нибудь (с корпусом пилота, строка 85) | размеченный класс → решение | 04-unhappy §5, D39.90 | -| 111 | **Дубль ключа пар-файла: фикс накрыл половину.** D39.82 закрыл строку 53 через `putUniqueDC` в `parseDCCheckers`, но генерик-парсер категорий `parseCategoryRows` (`internal/lang/langpack.go:806-826`, строка `cats[f[0]][f[1]] = val`) по-прежнему МОЛЧА last-wins — а якорь техдолга указывал именно на него. Пар-данные с опечаткой-дублем тихо теряют первую строку | бэкенд | когда-нибудь (малое касание, с любой правкой langpack) | fail-loud + тест | 13-tech-debt-anchors, D39.82, D39.90 | -| 118 | **tools/go.mod — РЕШЕНИЕ ПРИНЯТО (D39.97 п.4): строить отдельным малым паком.** `cmd/tmvet`+`internal/archguard` → отдельный модуль (`backend/tools/`); `make battery` гоняет оба модуля; `tool`-директива Go 1.24 НЕ решает (MVS общий). Выигрыш: бамп инструментов физически не двигает x/net/x/text. Sqlite 1.55 остаётся (D39.97 п.4) | бэкенд | скоро (до следующего бампа зависимостей) | малый пак по D39.97 п.4 | D39.96 п.6, D39.97 | -| 119 | **x/text-детерминизм: вердикт-несущие вызовы НЕ свёрнуты в версии (находки-5/6 приёмки).** `SanitizerVersion` не сворачивает ничего x/text-ного, а `detectCJKLeak` зависит от `width.Fold` (`sanitizer.go:211,687`) — смена x/text перевернула бы вердикт БЕЗ смены снапшота; `ExportNormalize` меняет экспортные байты вне хешей (`sanitizer.go:709`); `xTextVersion` пинит строку go.mod, НЕ скомпилированные таблицы — тулчейн go1.27 переключит x/text на Unicode 17.0.0 МОЛЧА (`tables17.0.0.go //go:build go1.27`; жилец реестра 108). Делать: явные версии-свёртки + механическую сверку «таблицы↔константа» вместо совпадения | бэкенд | скоро | правка версий-свёрток + тест | D39.96 п.6, отчёт §5 находки-5/6 | -| 120 | ⚠ **ЛИД УКАЗЫВАЕТ НА НЕСУЩЕСТВУЮЩУЮ ФУНКЦИЮ — испр. 05.09:** продового `buildCheckers` нет (`grep -rn 'buildCheckers' backend --include=*.go` → только тест-хелпер), и `lang.Load(` вне тестов не вызывается вовсе. Класс «бейзлайны ключуются по классу, не по паре» может быть жив — но искать его надо не здесь. ⚠ **Где искать (пере-снято 05.09): единственный прод-носитель бейзлайнов сегодня — `backend/internal/config/models.go`, и ключуются они по KIND ПРОВАЙДЕРА, а не по паре;** пара-специфика чекеров живёт данными `internal/lang`. ⇒ строка держится как ревью-вопрос общности («заработает ли пара, которой в репо НЕТ»), а не как известный адрес правки: **прежде чем строить — предъявить дефект на паре, которой нет.** **`buildCheckers` жёстко берёт `lang.Load(root,"zh","ru")`, бейзлайны ключуются по классу, не по паре (§7-8) — приезд ja-ru требует правки Go, против мандата общности §0.1.** Родня строки 115 (явный embed-список целей) — брать одним касанием | бэкенд | скоро | правка Go + тест на паре-которой-нет | D39.96 п.6, отчёт §7-8 | -| 121 | **archguard v2 — остаток (б)/(в)/(г)/(д); (0а)/(0б)/(а) ЗАКРЫТЫ дофиксом D39.97.** Полный фикс-лист посадок приёмки D39.96 с file:line — дословно в `architecture/13-tech-debt-anchors.md` §Б-121 | бэкенд | скоро (остаток: (б) тип вместо свитча · (в) build-теги · (г) 4-й анализатор · (д) семь пропусков) | правка анализатора + посадки | D39.96 п.2/п.6, отчёт §7-9/12/13 | -| 122 | **Гигиена пака стандартов — 11 микро-пунктов, не-блокеры приёмки (D39.96/97).** Полный список дословно — `architecture/13-tech-debt-anchors.md` §Б-122 | бэкенд | когда-нибудь | мелкие правки | D39.96 п.6, отчёт §7-6/7, §9 хвост | -| 123 | **Полигон: `jieba==0.42.1` — build-time зависимость артефакта контраста `eval/exp16/data/jieba_dict_general_zh.txt`** (пере-собран бэкенд-сессией 03.08, полный sha256 сошёлся с пином `16-bank-mining.md`); дописать в манифест окружения полигона с пометкой «build-time, не runtime» | полигон | когда-нибудь | строка манифеста | D39.96 п.6, отчёт §7-4/§6 | -| 124 | **Калибровка снапшота (вопрос владельца 04.08, разбор D39.97 п.5): нацеленность, не агрессивность.** ⚠ **Осей теперь ЧЕТЫРЕ — дописка D39.151:** (г) **идентичность оплаченной работы** («строка диспозиции ↔ вызовы, которые её оплатили») — переселена сюда из строки 195 решением владельца 17.08; родня оси (в), потому что массовое кросс-снапшотное переиспользование подрывает наивную атрибуцию по равенству снапшота; смежный носитель — §7 спеки D15.2. Прежние три оси одним дизайн-паком: (а) недо-чувствительность — вердикт-несущие вызовы x/text не свёрнуты (вход: строка 119); (б) пере-охват — `EmbeddedVersion` фолдит все пары разом → пер-парный хеш (родня 115/120); (в) дешёвая перекупка: `tmctl resnapshot --dry-run` — байт-сверка тел по чекпойнтам (`msgsContentHash`), идентичные юниты пере-привязываются без пере-вызова, платятся только изменившиеся. «Поведенческий отпечаток вместо строки версии» отложен (пол ≠ доказательство) | бэкенд | когда-нибудь (перед МАСШТАБОМ — когда перекупки станут реальными деньгами) | дизайн-пак по D39.97 п.5 | D39.97 | -| 221 | **Джойн «предложено × решено × нерешено» живёт ТОЛЬКО в движке.** Читаемый банк несёт итоги без предложений, карта подписи — предложения без решений; семантика «решено ли» (`ownerHandled`) существует в двух файлах движка и больше нигде (греп по трём зонам). Экран подписи при разморозке фронта заставит платформу пере-реализовать движковый закон у себя — дубль, запрещённый п.6 закона шва. **Фикс:** движок публикует нерешённость (секцией банк-экспорта или отдельной проекцией) — но ТОЛЬКО когда экран закажут: рефакторить под несуществующий экран не надо. Сейчас — ноль кода ⚠ **КОНСИЛИУМ 27.08 (оркестратор №19 + автор движковой двери), итог записан, чтобы его не выводили заново.** **(1) Это ОДИН дефект, а не три:** 221 и 224 — ось СОДЕРЖАНИЯ (проекция не несёт предложенное и не несёт джойн), остаток компаньона — ось СВЕЖЕСТИ (дверь пишет источники мгновенно, проекция ждёт границы прогона, которой при стоящем прогоне не наступает). Классический разрыв CQRS. Чинить порознь = три полу-лечения. **(2) Поле `BankTerm.decision` МЕРТВО СТРУКТУРНО** — довод сильнее прежнего «запрет владельца»: decline выражает себя ИСЧЕЗНОВЕНИЕМ строки, а не значением поля (`writeAutoBank` делает `continue` на `ownerHandled`, `mining.go:709+`), и негде показаться ни в одном из трёх окон; для approve поле избыточно — `status: approved` публикуется. Проверено двумя независимыми трассами. ⚠ Вопрос был СНЯТ ещё D39.144 вместе с ложной посылкой «марш к нулю, 17 из 300»; сегодняшняя потребность иная и уже — перезагруженный экран показывает СДЕЛАННЫЕ ПРАВКИ. **(3) Форма-кандидат Д′:** ДВЕ проекции, у каждой РОВНО ОДИН писатель — «решено на границе» пишет прогон рядом с картой, «решено после границы» пишет дверь при записи; экран склеивает по паре (поверхность, `map_id`), счёт приезжает ПОСЧИТАННЫМ. Правило единственного писателя остаётся буквально, поправка онтологии НЕ нужна. Конверт карты из дофикса-2 получает здесь первого потребителя. ⚠ Колонка `undecided` обязана ехать с тем же НЕ-гейтовым контрактом, что `SignatureState`, иначе пер-термная модель вернётся через новую проекцию. **(4) Подпункт «история»:** `glossary_revisions` построен наполовину — читатель вызывается только из тестов, графа `reason` заполняется литералом `seed-replace`, а ревизия пишется лишь для ОСТАВШИХСЯ строк, то есть журнал слеп к отклонениям; владельческий `note` доезжает до вида (`glossary.go:41,161`) и не публикуется ни одной проекцией. ⚠ Journal append-only: не заказать ревизии без исчезновений задним числом уже не выйдет. **Пак не заказан — ждёт слова владельца** | бэкенд | гейчена разморозкой фронта | аддитивное поле проекции | приёмка двери 27.08, D39.158 | -| 222 | **ВНУТРИкнижный остаток оси арбитра: второй конфиг ТОЙ ЖЕ книги с другим `project_db` пишет ту же пару файлов решений под ДРУГИМ локом**, мимо флока живого прогона. Достижимо по построению: пути решений считаются от каталога `book.yaml` и `book_id`, лок — от `project_db`. Рукотворная конфигурация оператора (две базы одной книге), лечение трогает ратифицированный п.2 закона (второй арбитр на идентичности файлов решений либо отказ при загрузке). ⚠ Межкнижная версия ЗАКРЫТА снятием объявляемых ключей (D39.158 п.5) | бэкенд | когда-нибудь (непропорционально: правка ратифицированного закона ради операторского футгана) | второй арбитр ЛИБО отказ при загрузке | приёмка двери 27.08, D39.158 | -| 223 | **Майнерский хвост за потолком структурно недостижим.** Потолок эмиссии (200) применяется ДО фильтров пригодности, сида и отказов, а детектор кандидатов сида и отказов не видит вовсе — репозиторий пишет это про себя дословно. Замер: 2110 ранжированных → 442 годных во всём алфавите → 117 внутри окна потолка → **325 невидимы постоянно**; отклонение всех 117 не подняло ни одного. ⚠ Решения владельца слотов НЕ освобождают, и это верно СЕГОДНЯ, а не следствие флажка; цитата «пере-предлагается once these are signed or declined» относится только к ОБРАТНОЙ секции. Двигать потолок — трогать фрозен-паритет, отдельное решение. Якорь-пин: `internal/miner/emissioncap_test.go` | бэкенд | когда-нибудь | решение о потолке, не правка | приёмка двери 27.08, D39.158 | -| 224 | **Банк-экспорт на стопе ПУСТ** — проекция, наиболее пустая ровно в момент, когда её читает экран подписи. Замерено: стоп с двумя предложенными термами даёт `total=0`, авто-банк на стопе отсутствует, потому что он пишется только в ветке авто-продолжения; при этом комментарий рядом называет стоп «границей, которую читает экран подписи», а платформа читает именно `.bank.json`. Член класса «проекция без контракта потребителя» (`architecture/18-bank-ontology.md`) ⚠ **ФОРМУЛИРОВКА ПРОТУХЛА, испр. оркестратором 05.09 по итогу стратегического веера:** лид говорит «экспорта на стопе нет, пишется только в ветке авто-продолжения» — сегодня `exportBank(ctx, "bank-mining/signature-stop")` НА СТОПЕ ЕСТЬ (`backend/internal/pipeline/mining.go`, греп `signature-stop`). Отсутствует не ВЫЗОВ, а НАПОЛНЕНИЕ: `exportBank` проецирует таблицу глоссария, а майненные строки попадают в неё только через `writeAutoBank`+`seedGlossary`, и оба лежат ВНУТРИ ветки `if !stopping`. ⇒ Экран подписи читает артефакт, гарантированно пустой ровно от тех строк, ради которых открыт. **Кто пойдёт чинить по прежнему тексту — будет искать несуществующий пропущенный вызов.** | бэкенд + платформа | скоро (держит экран подписи вместе с 221) | публиковать предложенное на стопе | приёмка двери 27.08, D39.158 | -| 225 | **Гейт «строка `open`, а лекарство уже в дереве».** При лендинге пересекать ПОЛНЫЕ пути застейдженных файлов с якорями открытых строк регистра и бэклога; совпадение — вопрос лендеру, а не находка следующего пака. Замерено прежде решения: по именам файлов 22 совпадения, почти все ложные; по полным путям 2, оба настоящие, и один из них (`PD-157`) убил мой же лендинг `d1eb8a9`. Норма-половина уже стоит в `platform/docs/ENGINEERING_STANDARDS.md` §3 п.8; здесь — машинная половина, режимом `counts.py` | оркестратор | скоро (окупился до постройки) | режим `counts.py`, берущий список путей и печатающий открытые строки, чьи якоря в них целят | приёмка пака P8-REVIEW 27.08, D39.159 п.7 | -| 226 | **История ПРЕДЪЯВЛЕННОГО не ведётся — «почему меня не остановило на этом термине» ответить нечем.** Карта и человеческая таблица стопа перезаписываются каждым прогоном, память флажка — плоское множество поверхностей без `map_id` и без времени. Это прямая расплата за то, что стоп срабатывает ОДИН раз (кластерная память, названный остаток дофикса-2), и единственная возможная диагностика спора. Кандидат в пак решённости, не заказ. ⚠ Шестое, названное консилиумом и оставленное владельцу: авторство и время решения — сегодня цена нуля (владелец один), станет нужным при мультипользовательской платформе, и тогда его захотят ЗАДНИМ ЧИСЛОМ | бэкенд | скоро (диагностики нет вовсе) | движок метит предъявленное `map_id` и временем; оверлей отвечает «что предъявлялось на прошлом стопе» | консилиум по читающей стороне банка 27.08 | -| 250 | **Заголовок глоссария на проводе ОПИСЫВАЕТ маркер, которого после пака больше нет — живая строка с висячей ссылкой.** Строка данных `ru glossary_header` (`backend/internal/lang/data/injection.txt`) дословно объясняет модели: «строки с пометкой ⟨проверить⟩ — неподтверждённые кандидаты», а пункт 3 вайр-батча снимает маркер с провода по `D39.104` п.2 ⇒ на проводе не останется НИ ОДНОЙ помеченной строки, а заголовок продолжит объяснять пометку. ⚠ Это НЕ мёртвая строка данных (те — `editor_unverified_header` и `unverified_marker`, они просто перестают читаться), это ЖИВАЯ строка, которую читает модель. По `D39.104` п.1 клаузула становится ВАКУУМНОЙ, а не ложной, вред не измерен — поэтому не блокер. ⛔ **Чинится ТОЛЬКО правкой `injection.txt`, а она двигает `EmbeddedVersion` → `cutTag` → ключ манифеста → снос `unit_resolutions` книги (строка 198).** Носитель — ближайшее ОКНО правки эмбед-данных: строка **160** идёт своим паком и всё равно бампает форму манифеста. Найдено бэкенд-сессией вайр-батча 04.09 — она правильно НЕ тронула и принесла предмет | бэкенд | скоро (в окне строки 160) | правка `injection.txt` в окне 160 | пинг бэкенд-сессии 04.09 | -| 251 | **Банковый контур в `pipeline-c1.yaml` требует АРТЕФАКТА, которого в git нет и быть не должно — первая же выкатка после лендинга откажется стартовать, если его не положили.** Оба банк-роля живут ВНУТРИ стопа майнинга, а `runBankMiningStop` (`backend/internal/pipeline/mining.go:58`) возвращается РАНЬШЕ построения кандидатов при пустом `mining.contrast_path` ⇒ без корпуса контраста терминолог и классификатор не исполняются ВООБЩЕ, чем бы ни были заполнены их гейты. Артефакт — общечастотный словарь jieba (`.gitignore:38`: «jieba 0.42.1 dict.txt, 5MB — SHA pinned in the report, **reproducible**»), рецепт и sha256 `7197c321…` — `docs/experiments/16-bank-mining.md` (греп `jieba_dict_general_zh`). ⚠ **Риск ограничен и это ГЛАВНОЕ:** артефакт не утерян, а ВОСПРОИЗВОДИМ по запиненному рецепту; дыра в том, что требование не доехало до РАНТБУКА развёртывания (`platform/deploy/README.md` о нём не знает), и оператор узнаёт о нём только от гарда. Гарды поставлены паком и они правильные: загрузка ОТКАЗЫВАЕТ при включённом гейте с пустым ключом, наличие файла проверяется на ПИШУЩЕМ пути рядом с `CheckKeys` — то есть до оплаченной черновой волны, а не после неё. ⛔ **Что делать:** требование в рантбук платформы (её зона, пинг) + слово владельца/оператора, что файл лежит на боевой машине, ДО первой выкатки после лендинга. ⚠ **Вторая половина, вскрытая тем же включением:** корпус контраста — факт ИСХОДНОГО ЯЗЫКА, а `mining.contrast_path` живёт в конфиге пайплайна, который по построению пар-агностичен (цель проекта №2). Перекос не заведён паком, а вскрыт им; пара, которой в репо нет, потребует своего корпуса и своего ключа | бэкенд+платформа | скоро (до первой выкатки после лендинга вайр-батча) | пинг рантбуку + слово оператора; пар-перекос — отдельным решением | бэкенд-сессия вайр-батча 04.09 | -| 252 | **Две гарантии не прибиты — мутации сессии ПЕРЕЖИЛИ всю батарею** (собственные посадки бэкенд-сессии вне шести пунктов заказа, 04.09; из восьми посадок шесть красные, две выжили и НЕ чинились как вне-заказные). **(а) `StickyDepth = 2 → 1` не ловит НИКТО** — глубина окна липкости меняется молча. **(б) `priorityRank`, отбрасывающий приоритет доверия** (подтверждённые строки раньше неоднозначных в бюджете инъекции), **не ловит НИКТО** — то есть порядок, решающий, ЧТО попадёт в инъекцию при нехватке бюджета, можно перевернуть безнаказанно. ⚠ Класс тот же, что дал паку «число согласия» три неприбитых свойства: заявленное поведение без пинящего теста. Сессия правильно НЕ чинила вне заказа и принесла предмет | бэкенд | скоро (ближайшим касанием инъекции) | по тесту на гарантию + запись в `cmd/tmmutate/mutations.json` | собственные посадки бэкенд-сессии 04.09 | -| 253 | **НА ЭКРАНЕ ПОДПИСИ БАНКА ПОДПИСЫВАТЬ НЕЧЕГО, а сам подписываемый банк НЕПОЛОН — две половины одного шва, найдены ПЕРВЫМ живым прогоном 04.09.** **(а)** ⚠ **ЭТО ТОТ ЖЕ ДЕФЕКТ, ЧТО СТРОКА 224 — испр. 05.09:** корень там уже найден и назван (майненные строки пишутся внутри ветки `if !stopping`), поэтому «разобрать порядок публикации» здесь заказывать НЕЛЬЗЯ — работа удвоится. Половина (а) закрывается лендингом 224; живой в этой строке остаётся только (б). Прогон встал `awaiting_bank`, `GET /bank` отдал `total 0, signed 0` — при том что рядом лежали `mined-signature.yaml` 49 КБ и `bank-stop.txt` 60 КБ, а движок держал 82 неразобранные поверхности; термины появились в read-модели только на СЛЕДУЮЩЕМ прогоне (`bank export refreshed … terms=83`). Платформа читает сайдкар честно: 0 значит 0 ⇒ либо сайдкар пишется не в тот момент, либо стоп наступает РАНЬШЕ публикации банка. Корень скорее движковый. **(б)** Банк, который пользователь подписывает, ЧАСТИЧНО КОНСОЛИДИРОВАН, и платформа об этом не знает вовсе: терминология урезала план под бюджет ДО первого вызова (`batches_dropped=5`, `consolidated=38 declined=0 unanswered=47` из 85), а поверхности нет ни одной — `grep -rn 'consolidat\|unanswered\|batches_dropped' platform/internal/ --include=*.go` → **0**, аллоулист сайдкара несёт только термины. ⇒ **пользователь подписывает как ПОЛНЫЙ банк то, что движок сам называет неполным.** Лечение (б) — КАНАЛ: полнота консолидации в сайдкар + поле на `BankPage`; лечение (а) — разбор порядка «стоп против публикации». ⚠ Обе половины на шве, чинятся согласованно | бэкенд+платформа | скоро (до первого внешнего пользователя) | разбор порядка публикации + канал полноты | наблюдение платформы за живым потоком 04.09, H10/H11 | -| 254 | **Шесть движковых ловушек, увиденных ПЕРВЫМ живым прогоном (04.09) и НЕ тронутых платформой — чужая зона.** ⚠ **ОДНА ИЗ ШЕСТИ РЕШЕНА ВЛАДЕЛЬЦЕМ 05.09 — остальные ПЯТЬ живы, строку не закрывать** (испр. 05.09; строка 285 закрывает ровно эту одну и не больше). ⛔ Решённая — самая дорогая: `manifest` на пустом файле даёт exit 11, а интейк на 11 УДАЛЯЕТ ЗАГРУЗКУ ⇒ пользователь, приславший пустой файл, терял его. **Лечение названо владельцем: fail fast на загрузке** — строка **285**. · `tmctl build` не читает контекст: всегда SIGKILL, staging-файл `.tmp-*` остаётся · потолок бросает летящие вызовы, они списываются нулём (`PD-441`, замер: отмены на 120756/156469/156470 мс) · терминология МОЛЧА режет план под бюджет (вход строки 253б) · сайдкар банка пуст в момент стопа (вход 253а) · **`build --format X` без `--out` удаляет соседние форматы** — ловушка для оператора с руками. ⚠ Ни один из шести не найден чтением кода за месяцы — все шесть увидены за один прогон | бэкенд | скоро (ближайшим касанием соответствующего пути) | по пунктам; часть — райдерами других паков | наблюдение платформы за живым потоком 04.09, H21 | -| 255 | **Первый живой прогон НЕ КОСНУЛСЯ поверхностей, ради которых часть кода построена — и это надо знать прежде, чем говорить «поток проверен».** **SSE-поток не открывался НИ РАЗУ** (весь прогресс читался поллингом ⇒ `platform/internal/httpapi/stream.go` живым прогоном не проверен вовсе) · читающая поверхность глав и пар не читалась · пользовательский `stop` не звался — из ТРЁХ способов кончить прогон проверены два · апгрейд движка, `books --migratable`, `run unquarantine` не трогались · всё измерено на книге **57 КБ**, на корпусной 23 МБ переносить нельзя. ⚠ Это не дефект, а ГРАНИЦА утверждения: «цикл замкнут живьём» верно ровно про ту цепь, которую прошли. Следующий платный прогон обязан закрывать этот список, а не повторять пройденное | платформа | скоро (следующий платный прогон) | список к покрытию | наблюдение платформы за живым потоком 04.09, H22 | -| 256 | **Лейбловая ветка `CheckKeys` прибита только СПИСКОМ — БЛИЗНЕЦ денежной дыры, закрытой на безлейбловой.** Безлейбловую ветку круг 3 починил определением `gateModels()` и прибил вызовом самого `CheckKeys`; лейбловая по-прежнему держится тестом на СПИСОК (`TestABankModelIsAReachableModel`) — тем самым способом, про который тот же круг записал «пин на списке не есть пин на префлайте». Посадка круга 4: лейбловая ветка собирает модели стадий вместо `ReachableModels()` — ВЕСЬ пакет зелёный. Проба предъявлена: лейблованная книга с банк-моделью на провайдере без ключа проходит префлайт целиком. Симптом денежный и тот же: покупается черновая волна, смерть на воротах. ⚠ Не чинилось только потому, что круг свёрнут решением владельца | бэкенд | скоро | пин на вызове `CheckKeys` для обеих веток + проба под лейблом | круг 4 петли, X40 | -| 257 | **Порядок `bound()` перед `reconcile` не держится ничем, и цена — исчезнувшее сообщение оператору.** Перенос блока `bound()` после `reconcile` пережил весь пакет. Проба: книга в одну главу, второй прогон под грантом 1, редактор отказывает — единственная работа вне гранта флагуется; оригинал печатает «1 PAID FOR BUT FLAGGED», под посадкой **отчёт об объёме = nil**, то есть раскрытие, ради которого он построен, пропадает целиком. ⚠ Комментарий коммита посылает читателя в юнит-тест `volumeScope`, который порядок в `waverun` увидеть не может — второй экземпляр класса «тест утверждает не то, что думает» | бэкенд | скоро | пин порядка в `waverun`, а не в `volumeScope` | круг 4 петли, X14 | -| 258 | **Конструктор `classifyInputFor` можно захардкодить на `ru`/`zh` — вся батарея зелёная, и причина СТРУКТУРНАЯ: через раннер нет ни одной фикстуры с не-ru целью.** Есть только zh→ru и ja→ru. Рефлексивный пин круга 3 ловит «поле нулевое», но не «поле взято не у книги». Пробы предъявлены: →ja книга с китайским выводом под посадкой перестаёт быть →ja. ⚠ Бьёт прямо в цель №2 (ревью-вопрос «заработает ли пара, которой в репо нет, без правки Go»): сегодня ответ на него не может дать ни один тест. Родня — 259 | бэкенд | скоро | фикстура не-ru цели ЧЕРЕЗ раннер + пин «поле взято у книги» | круг 4 петли, X1/X2/X3 | -| 259 | **Настоящей латинописьменной цели в репозитории НЕТ — `target-en.txt` не существует, и →en достижим только через пустое объявление.** Следствие: часть общности проверяется рассуждением, а не тестом, и пара, которой в репо нет, не может быть предъявлена живьём ни одним прогоном. Замер общности 04.09: ветвлений Go по конкретному языку два на обе зоны, оба — проверка на пустоту; книжной специфики в Go нет, кроме константы худшей строки банка (строка 40) | бэкенд | скоро (гейт второй пары) | минимальный langpack →en + прогон на нём | замер общности оркестратора 04.09 по требованию владельца | -| 260 | **Экран цели калиброван на ОДНОМ сянься и даёт ложный `off_target` на латинице-тяжёлом здоровом русском** (0.461 с пиньинем при пороге). ⚠ Ложный флаг ЭСКАЛИРУЕТ, то есть стоит ПЛАТНОГО хопа за здоровый текст — это деньги, а не только шум. Порог и пол улики обязаны быть пере-калиброваны на корпусе, включающем латиницу-тяжёлый русский | бэкенд | скоро | пере-калибровка на расширенном корпусе + пин границы | самоотчёт бэкенд-сессии о непокрытом, круг 3 | -| 261 | ⛔ **ОСТАТОК СНЯТОЙ СТРОКИ 277 ЖИВЁТ ЗДЕСЬ (возвращён 05.09 по ревью — при закрытии 277 он едва не потерялся): остаток `PD-441` = **261 + 262** (третья часть, строка 277, ПОСТРОЕНА и закрыта D39.206 — «одним паком» уже невозможно).** Пак «денежный стоп» (акт D39.206) снял только ОТМЕНУ допущенного; **структурный корень невидимого расхода — эта строка**, а сверх-утверждение комментария ветки отмены — строка **262**. ⇒ платформенной зоне: `PD-441` закрывать «паком денежного стопа» НЕЛЬЗЯ, он закрыт наполовину. **`BilledDecodeError` виден только когда ретрай НЕ спас: успешный ретрай стирает оплаченную попытку из леджера.** Тип заведён, чтобы оплаченный-но-нечитаемый вызов стал ВИДЕН (рантайм доседает по оценке), но `retryLoop` при успехе возвращает ответ и предыдущую ошибку выбрасывает — рантайм видит один успешный ответ и седит его `Usage`. Оплаченный 2xx перед ним не попадает никуда. ⚠ Бьёт не в отчётность, а в ЦЕЛОСТНОСТЬ потолка: допуск выдан под ОДНУ оценку, а под ней могло пройти до трёх запросов (`MaxAttempts` 3), и `Reserve` об этом не узнает. Комментарий рядом сам говорит «each retry is a new billed 2xx» — авторы знали и закрыли только детерминированный случай (усечение). ⚠ ЧАСТОТА пути НЕ измерена | бэкенд | скоро (вместе с денежным паком) | единица учёта = единица биллинга + вендор-факт по правилу квирков | чтение под вопрос, бэкенд-сессия 04.09 | -| 262 | **Комментарий ветки отмены — сверх-утверждение: «No 2xx ever arrived: nothing was billed» описывает ветку ШИРЕ, чем она есть.** Верно для отказа соединения, DNS, таймаута до первого байта и терминального 4xx; ложно для вызова, который отменили МЫ после начала генерации — он приходит в ту же ветку через `context.Canceled`. Правка отложена намеренно: ветка денежная, лечение структурное (см. 261), однострочная правка фразы разъедется с решением | бэкенд | скоро (вместе с 261) | привести ветку и её описание к одному радиусу | чтение под вопрос, бэкенд-сессия 04.09 | -| 263 | **Дизъюнкты предупреждения банкноты и `forWrite` не прибиты по отдельности** (позитивная фикстура без обоих входов, негативная — с обоими): пережили посадки «нет контраста», «нет пака», «предупреждать и на read-open». **`WB15` несёт тот же дефект ложного пина, что найденный и починенный `WB36`** — одиночный сдвиг порога под `TestGoldenDeterminism`: на чистом литерале голден не двинется и запись выживет при целой гарантии. **AST-тест исчерпаемости парсит ТОЛЬКО `disposition.go`** — `FlagReason`, объявленный в другом файле, в карту не попадёт при зелёном тесте. **Дайджест корпуса не покрывает `provenance`** — адрес пере-снятия, подмену которого дайджест не видит | бэкенд | когда-нибудь | четыре независимых пина | круг 4 петли, X11/X12/X13 · WB15 · X9 · X30 | -| 265 | **Питоново зеркало полигона держит ВТОРУЮ копию таблицы плейсхолдеров движка, и она разошлась: `genre` есть, `book_id` нет.** `eval/bank_arbitration/editor_wire_probe.py` — ПЛАТНАЯ проба, читающая ШИППИНГОВЫЙ `backend/prompts/zh-ru/editor.md`, на неё ссылаются ещё **25** скриптов (`grep -rl editor_wire_probe eval --include=*.py`; ⚠ испр. 05.09, первая редакция говорила «девять»); 27 промтов под `eval/` несут `{{genre}}`, который движок ОТКАЗЫВАЕТСЯ собрать при загрузке. ⇒ замеры идут на проводе, которого в проде не существует, и это «третий путь», которого в Go больше нет. ⚠ Зона ПОЛИГОНА — чинит она, носитель заведён оркестратором пингом | полигон | скоро (перед следующим платным замером) | зеркало читает таблицу движка, а не держит копию | передано бэкенд-сессией 04.09, чужая зона | -| 266 | **Правки кругов 3 и 4 петли не ревьюил НИКТО — круг свёрнут решением владельца, а не замкнут.** Замеренная база, из-за которой это долг, а не формальность: ДВАЖДЫ подряд дефект вносил фикс предыдущего круга (круг 2 объявил денежную дыру закрытой — круг 3 показал, что она открыта; ратификация оркестратора по дедупу внесла живой дефект — поймала зона). Круг 3 добавил ~2000 строк и не ревьюил из них ни одной; круг 4 — две правки, обе проверены исполнением, но не чужими глазами. ⚠ Дисциплина петли исправлена эрратой: круг крутит СЛЕДУЮЩАЯ сессия по готовому паку, а не прежняя — правило «сессия отрабатывает скоуп и завершается» бьёт норму петли | бэкенд | скоро | проход свежей сессии по диффу `c77c3ba`+`2e13cd1` | решение владельца 04.09 остановить полировку | -| 267 | ⛔ **ОДИН ТЕРМИН В ОДНОМ СМЫСЛЕ МОЖЕТ НЕСТИ ДВЕ КОНКУРИРУЮЩИЕ ФОРМЫ, И ОБЕ ЕДУТ НА ОБА ПРОВОДА — дыра в ПРОВЕРКЕ схлопывания.** ⚠ **Пере-снято 05.09: было заведено как ДОКТРИНА («показывать обе или схлопывать») — это была неверная постановка оркестратора.** Владелец: у неподписанного термина тоже обязан быть ОДИН перевод, отвечает за это стадия схлопывания, подпись ни при чём. **Измерено зоной по коду и предъявлено на банке:** ключ уникальности БД — `(book_id, src, sense, since_ch, until_ch)`, значит один смысл при РАЗНЫХ окнах законен для БД; гард «одна форма на главу» существует (`backend/internal/pipeline/memseed.go`, греп `a term has ONE rendering per chapter`) и статус-слеп, **но работает ВНУТРИ ОДНОГО ФАЙЛА** — `loadMinedDelta` проверяет дельту саму против себя и НЕ против сида; точка слияния (`bankmaterialize.go`, греп `storeOrder`) отвергает только ТОЧНЫЙ дубль, перекрывающиеся окна проходят. Предъявлено: сид `[0,0]` «юаньши» + майнинг `[3,9]` «камень первоисточника», глава 5 внутри обоих ⇒ **injected=2, две строки и редактору, и черновику**. ⇒ Банк перестаёт быть законом ровно там, ради чего построен — консистентность термина на всю книгу. ⚠ **ГРАНИЦА, названная зоной: доказано, что состояние ДОСТИЖИМО и провода его несут; НЕ доказано, что обычная последовательность операций его производит** (консолидация даёт один `dst` на термин — сверено; сверяет ли она предложение с УЖЕ существующей сид-строкой другого окна — не мерено). Это дыра в проверке, а не наблюдённый инцидент. Чинить на СЛИЯНИИ, где видны все три источника, а не на загрузке каждого | бэкенд | скоро | гард перекрытия окон на слиянии + пин на достижимом состоянии | решение владельца 05.09 + замер зоны | -| 268 | **Гейт версии контракта у фронта читает СВОЁ зеркало, а не канон — и потому слеп по построению.** `frontend/src/api/contract.test.ts` сверяет `${cwd}/docs/api-contract/openapi.yaml` с фикстурой, то есть копию с копией, и зелен при любом отставании; соседний тест сравнивает только МАЖОР, а он у `0.2.3` и `0.10.0` одинаков — ноль. Зеркало отстало на ВОСЕМЬ миноров. Сравнение: тот же класс гейта у платформы читает КАНОН с диска и поймал расхождение `0.9.0→0.10.0` в тот же час. ⚠ Зона фронта ЗАМОРОЖЕНА — строка ждёт разморозки, но входит в перечень первого касания | фронт | скоро (первое касание при разморозке) | перенацелить гейт на канон | находка платформенной сессии 04.09, подтверждена оркестратором | -| 272 | **ШАБЛОН КНИГИ ДЕПЛОЯ ОДИН НА ВСЕ ПАРЫ, а в нём лежит ПАР-СВЯЗАННОЕ значение — `transcription: palladius`.** Платформа рендерит `book.yaml` из единственного операторского шаблона и подставляет ровно пять ключей (`book_id · title · source_lang · target_lang · source_file`); всё остальное едет из шаблона нетронутым. Палладий — система транскрипции ДЛЯ КИТАЙСКОГО. Движок значение не валидирует (свободная строка) и подставляет прямо в промпт. ⇒ Деплой, объявивший `zh>ru,ja>ru`, отдаёт КАЖДОЙ японской книге инструкцию транскрибировать по-китайски: не отказ и не флаг, а тихо неверные имена во всей книге — ровно тот класс брака, ради которого продукт существует. ⚠ Чинить придётся не одну книгу: значение вшито в `book.yaml`, который платформа НИКОГДА не перезаписывает (`O_EXCL`) | платформа+бэкенд | скоро (гейт второй пары) | пар-связанные ключи шаблона + валидатор значения в движке | критик полноты стратегии 04.09 | -| 273 | **ПАР-ШОВ ЛОМАЕТСЯ АСИММЕТРИЧНО: промпт-пак падает ГРОМКО, целевые ДАННЫЕ выключаются МОЛЧА — вместе с банком.** Отсутствие промптов пары — жёсткая ошибка загрузки («never silently substitute another pair's conventions»). Отсутствие ЦЕЛЕВЫХ данных — тишина в трёх местах: `lang.InjectionTextsFor` на незнакомом таргете возвращает пустое, обе банк-инъекции рендерят пустоту (`if !tx.HasData() { return "" }`), `LoadReaderWords` отдаёт значки вместо слов без ошибки. ⇒ Книга на новый таргет переводится ЦЕЛИКОМ и за ПОЛНЫЕ деньги, но БЕЗ банка-как-закона — то есть без единственного механизма, держащего термины консистентными на всю книгу, без $0-чекеров цели и с пометками из значков в выданном файле. Ни ошибки, ни варнинга, ни поля в отчёте сборки. ⚠ Строка 32 закрыта формулировкой «инертна ПО ОТСУТСТВИЮ данных» — для ЧЕКЕРОВ это хорошо, для БАНК-инъекции такого вывода не делал никто | бэкенд | скоро (гейт второй пары) | префлайт готовности таргета: банк-данные есть ⇒ работаем, нет ⇒ громко | критик полноты стратегии 04.09 | -| 275 | ⚠ **ПЕРЕ-СНЯТА 05.09 СЛОВОМ ВЛАДЕЛЬЦА — прежняя формулировка «КАЧЕСТВО НЕ МОЖЕТ СТАРТОВАТЬ ВООБЩЕ» БЫЛА НЕВЕРНА (ошибка оркестратора).** Она называла четыре гейта; из них **три сняты словом владельца, четвёртый гейтом не был** (разбор — `D39.198`): **13а** веса рубрики НЕ НУЖНЫ — веса меряют РАЗНЫЕ узлы (консистентность — банк памяти, выдумки — редактор, художественность — редактор И черновик), единого веса быть не может, а одно взвешенное число измеряет, но не ДИАГНОСТИРУЕТ · **24** профили голоса — приоритет №3, подписи владельца не требуют («зачем мне это подписывать») · **149** разморозка панели не нужна: пока идут доработки, менять жильцов ролей незачем · **55** прогоняем на ТЕХ ЖЕ текстах (мастер Гу, Жан-Кристоф), оговорка про претрейн остаётся ОГРАНИЧЕНИЕМ ВЫВОДА, а не требованием новой книги. **ЧТО ОСТАЁТСЯ ЖИВЫМ В ЭТОЙ СТРОКЕ:** привязать каждый класс дефекта к УЗЛУ и мерить по узлам; поставить порог остановки для приоритетов №1 и №2 (разъехавшийся термин — стоп, выдумка — стоп, сухая фраза — не стоп). ⚠ Консистентность проверяема ДЕТЕРМИНИРОВАННО за $0 — это ГЕЙТ, а не строка рубрики; ближайший её носитель — строка **267** | полигон+бэкенд | скоро | привязка классов к узлам + пороги остановки для №1 и №2 | решение владельца 05.09, `D39.198` | -| 276 | ⭐ **ФОРМА ЗАКАЗА ПЕРЕВОДА — решение владельца 05.09, ратифицировано D39.196.** На аккаунте **баланс в ДЕНЬГАХ** и он виден. Человек стартует перевод; хочет задать потолок — тянет ползунок **в деньгах**; рядом ответ на его настоящий вопрос: **хватает на полную книгу или нет**. Хочет задать объёмом — второй ползунок: **ГЛАВЫ когда книга распозналась**, **ЗНАКИ когда нет** (о нераспознавании говорим ЯВНО). Старт = **холд с баланса**. Отдельная кнопка **«перевести книгу целиком»** — за целую книгу оценка точнее, чем за произвольный кусок. ⚠ **Две ручки связаны проекцией:** объём — ЗАКАЗ (главная), деньги — ЛИМИТ (вторая); тронутая последней ограничивает, другая пересчитывается и показывается производной («5 глав ≈ $0.55, зарезервируем до $0.8»); минимум денежного ползунка = неделимый шаг движка, чтобы ползунком нельзя было выразить невозможный заказ. Не тронута ни одна ⇒ заказ = вся книга. ⚠ **Цифра на экране — ПАРА, а не точка:** «ожидаемо ≈ $1.1, зарезервируем до $1.6, спишем по факту», и закрытие фактом после прогона — проекция имеет дисперсию (редакторские вызовы 25–90 % worst-case), точечное число превратится в «сказали 1.14, списали 1.31». Главный ответ — фраза, цифра рядом и мельче. ⚠ **Запрет «денег в UI» ОТОЗВАН владельцем** (D39.196 п.2): виден баланс, потолок, холд; цены моделей и стадий — нет. «Страница» из контракта убирается совсем — владелец назвал ЗНАКИ, форматирование «≈67 стр.» это локаль фронта. Исполнение — **279–283** (⚠ испр.: 277 и 278 ПОСТРОЕНЫ лендингом `81a89e9` и сняты) | движок+платформа+фронт | скоро | решение принято и ратифицировано D39.196; исполняется **279–283** (277 и 278 закрыты) | решение владельца 05.09 + сведение с внешним рецензентом | -| 279 | ⚠ **ПРОТУХЛА — испр. 06.09: половина ИСПОЛНЕНА без пометки, половина осталась остатком без имени.** Форма `OrderOptions` (`chapters_left`, `affordable_chapters`, `verdict`) стоит в каноне с минора 0.11.0, а `shortfall` в каноне ОТСУТСТВУЕТ (ноль вхождений); тело `D39.208` строку не называет, ✅ не стоит. Класс `D39.167` п.1: акт лендинга обязан быть сверен со строками. ⇒ разделить: исполненное пометить, остаток `shortfall` назвать своим предметом. **ШАГ 3, КОНТРАКТ (минор, полоса ломающих правок мажора 0 законна): заказ объёмом.** `ceiling_chapters` → `chapters` со смыслом ОБЪЁМА (`null` = вся книга) · `CeilingBounds{min,max,default}` → `OrderOptions{chapters_left, affordable_chapters, verdict: covers_all|covers_part|covers_none, blocked}` · `PausedReason` += `run_limit_reached` (и `credit_exhausted` СТАНОВИТСЯ правдой — сегодня лжёт при 34% баланса, наблюдение H14) · `Run` += `ordered_chapters`/`delivered_chapters`. ⚠ Фразы — ДАННЫМИ по коду причины и локали, не литералом. ⚠ **ПЕРЕ-СНЯТО 05.09 под D39.196:** наружу ВЫХОДЯТ баланс, потолок заказа и холд — деньгами; контракт получает `balance`, `estimate{expected, hold}` под выбранный заказ, границы денежного ползунка `{min: неделимый шаг, max: баланс}` и `shortfall` у паузы; процент остатка остаётся СИГНАЛОМ «мало/пусто». НЕ выходят: цены моделей, стоимость стадий и вызовов, структура НАШИХ расходов. Плюс `OrderOptions` обязан нести ТРИ вида заказа (вся книга · знаки · до главы N), а не только главы. Ремедиа-таблица `resumeRun` упрощается: «Продолжить» — новый прогон ТОГО ЖЕ заказа | контракт | скоро | минор контракта одним актом с платформенной половиной | согласование 04.09 | -| 280 | ✅ **ИСПОЛНЕНО ЛЕНДИНГОМ 06.09 — акт `D39.208`.** Заказ живёт на КНИГЕ и хранится ИДЕНТИЧНОСТЬЮ (`books.ordered_through_chapter_id`), а не ординалом; холд считается от проекции движка; `--max-units` едет в argv. ⚠ **Кроме ОДНОЙ позиции, от которой зона отказалась с доводом и которая живёт отдельно:** денежный ползунок объявлен на проводе, но отправить его нечем, и оценки под ВЫБРАННЫЙ заказ нет. Прежняя редакция ряда: **ШАГ 4, ПЛАТФОРМА: заказ живёт на КНИГЕ, холд считается от проекции, `--max-units` наконец едет в argv.** `books.ordered_through_chapter` (null = вся книга) — сегодня интент живёт на ПРОГОНЕ, оттого и неловкость «поднять лимит = НОВЫЙ прогон с бо́льшим `ceiling_chapters`»; с заказом на книге «Продолжить» после пополнения тривиален, и дверь пере-прохода встаёт рядом вторым типом заказа. Холд = `min(баланс, проекция × k)`; `bookCap = committed + холд` (`PD-158` цел). В argv добавляется `--max-units` = сумма юнитов заказанных глав минус доставленные. Удаляются `DefaultPerChapter`, `Scale` и `draftWork`: план движка становится РАВЕН заказу, и «черновики на весь потолок при нуле готовых глав» исчезает структурно. Закрывает `PD-410`, `PD-440`, `PD-446`. ⚠ **ПРЕДУСЛОВИЕ, названное отдельно: `PD-422`** — `--resnapshot` передаётся УСЛОВНО, а условие ставит только правка банка; рост авто-банка от майнинга флага не ставит. Частичный заказ на майнящей книге растит банк ⇒ следующий заказ без `--resnapshot` умрёт на снапшот-гарде, холд взят, попытка сожжена. Взять В ТОТ ЖЕ пак | платформа | скоро | заказ на книге + холд от проекции + проводка `--max-units` + PD-422 | согласование 04.09 | -| 281 | **ЗАМЕР: сколько наших денег стоит тысяча ПЛОТНЫХ и тысяча РАЗРЕЖЕННЫХ знаков по стадиям и парам.** Цель — НЕ константа (D39.165 п.1г прямо запрещает ставку константой), а **дисперсия проекции**: коэффициент k для холда и честность вердикта «хватит ли». Снимать есть из чего и это $0: `find -L books` даёт 162 базы прогонов, в `request_log` лежат `chapter · chunk_idx · stage · prompt/completion_tokens · cost_usd · tm_hit`, исходник по юниту отдаёт `tmctl export --pairs` бесплатно. Метод: по юниту плотные/разреженные знаки против суммы `cost_usd` при `tm_hit=0`, по стадиям; хвост ретраев и эскалаций считать ОТДЕЛЬНО; базы до 16.08 пере-прайсить по токенам. ⚠ Гейт для коэффициента холда в строке 280 | полигон | скоро (гейт строки 280) | замер по 162 базам, $0 | согласование 04.09, вторая редакция | -| 282 | ⛔ **ЧИСЛО, ПОДПИСАННОЕ «ЗНАКОВ», СЧИТАЕТ РУНЫ ПОТОКА ЗАПИСИ ФАЙЛА — что для UTF-8 txt И ЕСТЬ знаки, а для EPUB даёт руны ZIP-АРХИВА.** ⚠ Заголовок первой редакции («считает байты») — противоположная полуправда, испр. 05.09: ложно оно для EPUB, GB18030 и UTF-16, а не всегда. Проверено оркестратором по коду: `platform/internal/books/books.go`, греп `type counter` — счёт идёт по не-продолжающим байтам UTF-8 ПОТОКА ЗАПИСИ файла, а не по тексту; там же комментарий признаёт приближение для GB18030. Наружу уходит как `character_count` (`platform/internal/httpapi/v0.go`), на экране подписано `'about.characters': 'Знаков'` (`frontend/src/i18n/ru.ts`). ⇒ Живая ложь на продуктовом экране, и она же — вторая ненадёжная единица, найденная тем же вопросом «откуда берётся число». **Основой страницы быть не может.** Лечение: переименовать в размер файла ЛИБО заменить манифестной суммой знаков движка — ✅ **источник ПОСТРОЕН**: `source_chars` по юниту в `manifest --json` (лендинг `81a89e9`, акт D39.206; строка 278 закрыта и снята). Остаток строки — платформенная половина: взять число и снять ложную подпись. ⚠ Фронт заморожен — подпись правится при разморозке, число на платформе раньше | платформа+фронт | скоро | снять ложную подпись + заменить источник на манифест движка | согласование 04.09; проверено оркестратором по коду | -| 283 | **СТРУКТУРА ГЛАВ ДЛЯ ВЫДАЧИ — отдельная задача, которую «страница» НЕ отменяет, и она гейтит бету для не-CJK и EPUB.** Билдер кладёт по одному XHTML на главу движка и сам признаёт, что ридер делает главу из каждого документа spine (`backend/internal/bookfile/epub.go`) ⇒ **для не-CJK txt читатель получает книгу ОДНИМ ПОЛОТНОМ при любой единице заказа**. Состав — этап 1 `research/27`: EPUB по nav/NCX (обязательно по стандарту), FB2, индуктор оглавления для txt, разрез по ДАННЫМ ПАРЫ вместо захардкоженного CJK (сегодня асимметрия: распознавание строки-заголовка данные пары читает — `configs/langpacks/zh-ru/heading.txt`, — а РАЗРЕЗ на главы нет). ⚠ Делать в единственном окне пере-снапшота, пока платная книга одна: перекрой двигает нарезку. Пере-скоуп строк 160–162 | бэкенд | скоро (ДО открытия беты не-CJK и EPUB-входам) | этап 1 research/27 своим паком | согласование 04.09, вторая редакция | -| 284 | **НАЗВАНИЕ КНИГИ И ЗАГОЛОВКИ ГЛАВ ИДУТ ЧЕРЕЗ ТЕРМИНЫ — ОТДЕЛЬНОЙ СТАДИЕЙ (решение владельца 05.09).** ⚠ **СЮДА ЖЕ ПЕРЕЕХАЛ ОСТАТОК ЗАКРЫТОЙ СТРОКИ 274 (D39.201 п.7): доставка имени В ФАЙЛ.** Платформенная половина построена — имя вычисляется ПРИ СКАЧИВАНИИ (`platform/internal/httpapi/v0.go`, греп `exportName`), внутрь файла не пишется намеренно: движок сворачивает `title` в `BriefHash` → снапшот → каждый request-hash, то есть запись в `book.yaml` отказала бы следующему прогону недопереведённой книги и стоила бы ПЕРЕ-ОПЛАТЫ книги целиком. **ФОРМА ОПИСАНА, ПАТЧ НЕ ПРОВЕРЕН** (слово платформенной зоны, принято дословно): путь — `tmctl build --title` аргументом при спавне, прецедент `--ceiling-usd`, но НЕ предъявлено исполнением, что движок примет незнакомый флаг без правки разбора аргументов — по закону шва там громкий отказ по построению. Остаток регистра — `PD-450`. Сегодня их не переводит НИКТО: `dc:title` берётся из `book.yaml` как есть (`backend/internal/bookfile/epub.go`, греп `dc:title`), заголовок главы собирается детерминированно шаблоном из langpack (`backend/configs/langpacks/zh-ru/heading.txt`, `template Глава {n}`). ⇒ Русский EPUB приезжает в читалку с китайским названием — ломается первое, что видит человек. Владелец: «пусть едет как термины, причём отдельные, то есть как-то надо называть эту стадию». ⚠ Значит у стадии своё имя, свой бюджет и своя ПОДПИСЬ: название книги владелец утверждает так же, как утверждает термин. ⚠ Родня — строка 274 (ручка переименования у пользователя) и открытый лист владельца «что печатать на титуле и в имени файла» (D25.1): механизм строится, СЛОВО остаётся за владельцем | бэкенд | скоро | стадия перевода заголовков + подпись владельца | решение владельца 05.09 | -| 285 | **FAIL FAST ПРИ ЗАГРУЗКЕ вместо приёма-и-удаления (решение владельца 05.09).** Сегодня при загрузке проверяется ТОЛЬКО размер (`platform/internal/httpapi/middleware.go`, греп `LimitBody`); понять, есть ли в файле книга, умеет лишь движок и лишь при разборе — то есть ПОСЛЕ приёма и записи, а на классе «источник нечитаем» интейк УДАЛЯЕТ загрузку. Владелец: «почему просто не fail fast, как это обычно принято». ⚠ Механизм для этого есть и он $0: `tmctl manifest` режет книгу и возвращает число юнитов без ключей и без единого платного вызова, и платформа уже умеет его звать. Звать СИНХРОННО на загрузке: либо человек сразу видит «в этом файле книги нет» и файл не принят вовсе, либо получает принятую книгу и её объём. ⇒ **Снимает вопрос про удаление целиком — удалять нечего, если не приняли** (строка 254 закрывается этим). ⚠ Решить: латентность синхронного разбора на большой книге и что показывать, пока он идёт | платформа | скоро | синхронный $0-разбор на приёме + отказ вместо удаления | решение владельца 05.09 | -| 286 | ⚠ **ЧИТАТЬ ЧЕРЕЗ `D39.205`: стоп остаётся ЦЕЛЬЮ, но гейт `gates.glossary.postcheck_gate` владелец 05.09 ОТЛОЖИЛ до замера точности («Не знаю. Тут надо мерить типо?… ложные срабатывания — это плохо, очень плохо») — это отсутствие замера, а не запрет** («ложные срабатывания — это плохо, очень плохо»); предусловие — строки 295 и 12. ⚠ **Сюда же перенесён 06.09 «ДЕТЕКТОР ВЕРНОСТИ ЗНАЧЕНИЯ» из строки 318** — четвёртым носителем одного вопроса он был бы трекерной инерцией: прибор, проверяющий вложенный `dst` ПО ИСХОДНИКУ, — тот же самый, что линза строки 319 после починки, а $0-прототип уже назван строкой 12. ⇒ **строка 318 остаётся только конкретной правкой** (комментарий постчека привести к поведению плюс пин), а вопрос «чем ловить неверное ЗНАЧЕНИЕ» живёт здесь и упирается в замер точности, а не в код. ⛔ **ПРИОРИТЕТ №1 ВЛАДЕЛЬЦА («100% консистентность») НЕ ИСПОЛНЯЕТСЯ КОДОМ И ПРОТИВОРЕЧИТ ДЕЙСТВУЮЩЕМУ ПОРОГУ.** Найдено ревизией документации 05.09. Три расхождения, каждое с носителем: **(1) ПОРОГ.** `docs/architecture/02-mvp-plan.md` и реестр `D10` держат «≥98%» — владелец 05.09 сказал **100%** (`D39.198`). Два процента на книге в тысячи терминов — это десятки разъехавшихся имён. **(2) МЕХАНИЗМ.** Единственный сегодняшний носитель консистентности — флаг `glossary_miss` РАНГА 5, то есть замечание, **с которым текст ОТГРУЖАЕТСЯ** (`backend/internal/pipeline/status.go` + `disposition.go`, греп `FlagGlossaryMiss`). Владелец сказал «разъехавшийся термин — СТОП». Флаг стопом не является. **(3) СЕМАНТИКА.** Приоритет №2 («никаких выдуманных сюжетных линий и смыслов») не имеет носителя вовсе: в реестре требований такого ПТ нет, ближайшее — гейт по ДЛИНЕ, а не по смыслу; семантический судья в движке не построен (слой 5). ⇒ **Сессия качества, собранная по нынешним докам, построит от неверной цели.** ⚠ Родня: строка **267** (две конкурирующие формы одного термина доезжают до редактора) — она и есть живой экземпляр нарушения приоритета №1 | бэкенд+полигон | скоро | порог 100% в носителях · консистентность как СТОП, а не флаг · носитель для приоритета №2 | ревизия документации 05.09, `D39.198` | -| 287 | **ТЕСТ ИСЧЕРПАЕМОСТИ ФЛАГОВ СЛЕП НА ТРЕТЬЮ ЛЕГАЛЬНУЮ ФОРМУ Go — найдено ПОСАДКОЙ верификатора приёмки, не автором.** Тест читает объявления причин через `go/ast` и покрывает две формы (`X FlagReason = "…"` и `X = FlagReason("…")`), о чём говорит его собственный комментарий «BOTH GO SPELLINGS COUNT». Третья форма — типизированная спека со значением-конверсией (`const X FlagReason = FlagReason("…")`) — **ПЕРЕЖИВАЕТ посадку**: типизированная ветка ждёт `*ast.BasicLit`, получает `CallExpr`, `lit == nil` и молча продолжает. Пол `found < 15` её тоже не ловит. ⚠ **Это ГРАНИЦА, а не живая дыра:** ни одной такой формы в дереве сегодня нет (все константы в `disposition.go` типизированные) — но комментарий обещает больше, чем тест держит, а это тот самый класс «утверждение шире ветки», который пак ловил четырежды. Там же не назван и `var`-случай. | бэкенд | когда-нибудь | покрыть третью форму ЛИБО сузить комментарий до двух | верификатор приёмки 05.09, посадка вне списка автора | -| 288 | ⛔ **«ПОПРАВИЛ ЧИТАТЕЛЯ, ОСТАВИЛ ПИСАТЕЛЯ» — ЕЩЁ ОДНО ПОЛЕ РЯДОМ, и оно бьёт в цель №2.** Сессия прибила читателя `classifyInputFor` и писателя `SetSourceScripts`; СОСЕДНЯЯ строка того же `defer` в `loadLangPack` — `backend/internal/pipeline/runner.go`, греп `CompileCheckersFor(r.pack, lang.TargetChecksFor` — не прибита ничем. **Предъявлено посадкой верификатора:** подмена `TargetChecksFor(r.Book.TargetLang)` на `TargetChecksFor("ru")` оставляет ВЕСЬ пакет `pipeline` зелёным (`ok 65s`). ⇒ Книга на →ja с включённым санитайзером компилировала бы РУССКИЕ паттерны читаемости: ложные `sanitizer_defect`, а ложный флаг ЭСКАЛИРУЕТ — это платные хопы за здоровый текст. От этой строки зависят `TargetActive()`, ёфикатор и латинский гард. Пин строится тем же двухкнижным приёмом, что и у `SourceScripts` | бэкенд | скоро | пин писателя целевых чекеров двумя книгами | верификатор приёмки 05.09, посадка вне карты отчёта | -| 289 | ⛔ **ДВЕ ВЕТКИ `CheckKeys` ДАЮТ ПРОТИВОПОЛОЖНЫЙ ОТВЕТ НА ОДИН И ТОТ ЖЕ КОНФИГ, а новый тест закрепляет лейбловую на фикстуре, где её собственная посылка ЛОЖНА.** Безлейбловая ветка требует ключ хопа ТОЛЬКО при `Escal.BudgetUSD > 0` (и это ратифицировано комментарием); лейбловая берёт `ReachableModels()`, куда `ResolvedHop` попадает БЕЗУСЛОВНО. При бюджете 0 хоп в рантайме не стреляет никогда. Зонд верификатора: одна стадия с `escalate_to` на провайдере без ключа, бюджет 0 ⇒ безлейбловая `nil`, лейбловая `missing API keys`. ⚠ Что внёс `74ffe4f`: кейс «the stage's escalation hop» и `why` записи `WB65` («a labelled run CALLS its escalation hop») стоят на фикстуре БЕЗ бюджета — то есть тест ПИНИТ требование ключа для модели, которую этот прогон вызвать не может. **Зеркало класса, который пак сам и нашёл: пин на «достижима» не есть пин на «вызывается».** Лечится либо бюджетом в фикстуре, либо приведением веток к одному правилу | бэкенд | скоро | свести ветки к одному правилу ЛИБО починить посылку фикстуры | верификатор приёмки 05.09, зонд вне карты | -| 290 | **ARM 1 нового теста банкноты проходит ВАКУУМНО, если каталог пары переедет — класс `WB41`, названный самой сессией.** Тест вписывает `langpack_root`, но не проверяет, что пак ЗАГРУЗИЛСЯ (`r.pack != nil`). Предъявлено: с несуществующим корнем все три плеча зелёные, а посадка `WB58` (снятие плеча контраста) **ПЕРЕЖИВАЕТ**. То есть красный `WB58` держится не тестом, а наличием каталога на диске. Лечение — посылка о состоянии пака в самом тесте. ⚠ Тот же класс: **тест исчерпаемости флагов слеп ещё на ДВЕ формы** сверх найденной первым верификатором — `var X = FlagReason("…")` на уровне пакета и `const` ВНУТРИ тела функции: обе посадки прошли, ни пол `found < 15`, ни сверка с картой не сработали (объявлено 17, найдено 16, карта 16). Итого форм пять, тест держит две, комментарий обещает «обе» | бэкенд | скоро | посылка о загрузке пака + покрыть или сузить обещание исчерпаемости | верификаторы приёмки 05.09 | -| 291 | ✅ **РЕШЕНО ВЛАДЕЛЬЦЕМ 05.09 (`D39.204`): деградировать во ФЛАГ, отличный по причине от исчерпания регенераций; текст попытки 0 оплачен и отгружается, волна идёт дальше. Вариант «минимальная покупка ≥ `step_max_usd`» СНЯТ — он стоил бы покупателю входного порога в пять глав. ⚠ Работа СВОИМ паком движка (правка пути ошибки в `stagerun.go` + новая причина флага + пин «купленное доставлено ⇒ не `exit 4`»), в принятый пак не дописывается.** ⛔ **ОБЯЗАТЕЛЬСТВО, БЕЗ КОТОРОГО ПАК НЕПОЛОН: новая причина флага выходит ОДНИМ АКТОМ С ПЛАТФОРМЕННОЙ ПОЛОВИНОЙ.** Карта заметок платформы РУКОПИСНАЯ (`platform/internal/ingest/notes.go`) и уезжает независимо от словаря движка; цена несделанного замерена — `PD-246`/эррата 04.09-в: минор 0.10.0 сутки жил ЛОЖНЫМ на проводе, причина доезжала читателю как `unspecified`, поймала это зона своей пере-проверкой ПОСЛЕ слов оркестратора «приёмка закончена». ⇒ промт этого пака обязан назвать ОБЕ зоны, а акт — предъявить зеркало. ⚠ Записано СТРОКОЙ, а не каналом, по слову сдавшей зоны: «`/tmp/textmachine-channel` не переживает рестарт — это в него и заложено», и обязательство, живущее в переписке двух сессий, умирает вместе с ними. ⚠⚠ **НИЖЕ — ИСТОРИЧЕСКИЙ РАЗБОР, ПО КОТОРОМУ РЕШАЛИ; как ЖИВОЕ не читать.** Его фраза «ВЫБОР НЕ СДЕЛАН» противоречит голове этой же строки — выбор СДЕЛАН владельцем (`D39.204`). ⛔ И ссылка «смена `D2.3`» в нём НЕВЕРНА ДВАЖДЫ, проверено по телу ноты (`../archive/architecture/05-decisions-D1-D38.md`, греп `^## D2. Диспозиция`): **(1)** `D2` уже кончается флагом («ретрай с бо́льшим `max_tokens` до капа, потом флаг») ⇒ это ДОСТРОЙКА, а не смена; **(2)** `D2.3` — по правилу подномеров ПУНКТ 3 тела `D2`, то есть «детектор вырождения перед удвоением `max_tokens`», к деградации отказа резервации отношения не имеет. **Настоящий адресат — `D2` п.2 «Тегировать `flag_reason`»**, и он делает вывод СИЛЬНЕЕ: тегирование причины там уже ТРЕБУЕТСЯ ⇒ новая причина есть **новый тег под существующим правилом**, а требование «причина обязана отличаться от исчерпания регенераций» — не добавка к канону, а его ИСПОЛНЕНИЕ. ⚠ Голова и хвост одной строки противоречили друг другу о состоянии решения — тот же класс, что находка `F7` приёмки, только не в коде, а в бэклоге; поймала сдавшая зона движка уже после закрытия своего пака. **ОТКАЗ РЕЗЕРВАЦИИ НА РЕТРАЕ НЕ ДЕГРАДИРУЕТ И НЕ ОСТАВЛЯЕТ СЛЕДА — юнит может заклинить НАВСЕГДА, а волна не может продолжиться без дыры.** `maxTokensForAttempt` удваивает бюджет на каждой регенерации (`backend/internal/pipeline/disposition.go`, греп `maxTokensForAttempt`), так что attempt 1 резервирует вдвое больше attempt 0. Отказ ретрая уходит наверх из цикла попыток (`backend/internal/pipeline/stagerun.go`, греп `return nil, err` в цикле попыток) **РАНЬШЕ `UpsertChunkStatus`** ⇒ чекпойнт attempt 0 есть (реплей за $0), **строки `chunk_status` НЕТ**, читающие модели видят юнит как `pending`, экспорт не отдаёт ничего. **Следствия два.** (1) Если потолок покупки не вмещает attempt 1 — юнит не доделается НИКОГДА: каждый резюм реплеит attempt 0 за $0 и умирает на attempt 1, прогон уходит exit 4 при ПОЛНОСТЬЮ доставленных купленных юнитах. (2) Продолжить волну после отказа ретрая нельзя без ДЫРЫ в непрерывном префиксе — то есть цена глобальной защёлки (недодача юнитов, которые влезали; разброс резервов внутри волны замерен ×2.976) различителем «свежий/ретрай» НЕ снимается. ⚠ **Оркестратор предлагал такой различитель на посылке «ретрай оставляет ФЛАГОВАННЫЙ юнит» — посылка ЛОЖНА, опровергнута зоной по строкам.** **Два пути лечения, ВЫБОР НЕ СДЕЛАН:** (а) отказ ретрая деградирует во флаг attempt 0 — смена `D2.3`, закрывает ОБА следствия; (б) минимальная покупка платформы ≥ `step_max_usd` движка (он включает ретраи именно поэтому) — закрывает только (1) и стоит продукту минимальной покупки ~5 глав | бэкенд+платформа | скоро | выбор владельца между (а) и (б) + пин | бэкенд-сессия денежного стопа 05.09, формулировка зоны | -| 292 | ⛔ **ЧЕСТНОСТЬ ТРЁХ СТРОК НАБЛЮДАЕМОСТИ — ЖИВАЯ ПОЛОВИНА (б) ЗАКРЫТОЙ СТРОКИ 105, заведена 05.09 отдельным носителем.** Закрытие 105 сняло только половину (а) — предикат `isBankRole`; половину (б) чинить никто не заказывал, а на неё ссылались ДВА носителя как на «до фикса 105». Три дефекта, все воспроизведены: **(1)** строка `VOICE` берёт `rules=` из конфига ВРЕМЕНИ ОТЧЁТА (`backend/internal/pipeline/quality.go`, греп `rules=`), поэтому включение `gates.voice` ПОСЛЕ прогона печатает «измерено, чисто» для книги, которую никто не мерил; **(2)** та же строка печатается при ВЫКЛЮЧЕННОМ гейте, если `SpoilerLeaks>0` — поведение верное, неверна формулировка отчёта; **(3)** знаменатель `BANKNOTE` = `len(states)` вместе с призрачными строками `retrieval_state`, тогда как соседний агрегатор их фильтрует ⇒ после пере-чанковки покрытие ЗАНИЖАЕТСЯ. ⚠ Цена молчания прямая: отчёт говорит «измерено», когда не мерили, — это ложь читателю в том самом месте, куда смотрят, решая, готова ли книга. Печатает `cmd/tmctl/render.go` (греп `rules=`), пин — `render_observability_test.go`. | бэкенд | скоро | правка формулировки + знаменателя + тест на «включил гейт после прогона» | D39.86, D39.200; археология — `architecture/13-tech-debt-anchors.md` §Б-105 п.(б) | -| 293 | ⛔ **ФАЙЛ ПОД ЛЮБЫМ КАТАЛОГОМ `books/` НЕВИДИМ ДЛЯ GIT — `git status` его не показывает, `git add` молча не берёт, и сдающая зона теряет работу, не заметив.** Предъявлено 05.09 платформенной сессией и проверено оркестратором до лендинга: `git check-ignore -v platform/internal/books/counter_test.go` → `/info/exclude:9:books`. **Причина: правило `books` в `.git/info/exclude` НЕЯКОРЕНО**, а gitignore без ведущего `/` ловит каталог с этим именем на ЛЮБОЙ глубине. ⚠ Неякорность ОСМЫСЛЕННА и снимать её нельзя не думая: `books` в связанном рабочем дереве — СИМЛИНК, а трекнутое правило `/books/` матчит только каталоги (комментарий стоит там же). ⚠ **Почему это не поймал никто:** тронутые файлы того же каталога в `git status` ВИДНЫ (игнор действует лишь на неотслеживаемое), поэтому пропажа не читается глазами; а `git commit -- <путь>` untracked роняет и без игнора. Замер: без `git add -f` уехал бы 31 файл из 32. **Лечение — не «поправить exclude»:** файл ОБЩИЙ для всех рабочих деревьев клона, включая полигонное, и менять семантику игнора под живыми сессиями нельзя. Формы, между которыми выбирать: (а) якорить правило под КОНКРЕТНЫЙ симлинк (`/books` в корне дерева) и проверить, что симлинк по-прежнему игнорируется во ВСЕХ деревьях; (б) оставить как есть и завести проверку лендинга — `git status --ignored --short <зона>` перед каждым актом. | оркестратор | скоро (гигиена лендинга, $0) | выбор формы + проверка во всех воркtree | предъявлено платформенной сессией 05.09; проверено исполнением при лендинге `7e2226a` | -| 294 | ⭐ **ФОРМА «СКОЛЬКО ДОБАВИТЬ» — решение владельца 05.09, ратифицировано `D39.203`.** Наружу вместо «сколько не хватило на ЭТОТ вызов» едет **«сколько добавить, чтобы прошёл ЛЮБОЙ следующий»** = `max(shortfall, step_max − headroom)`: сегодняшняя недостача закрывает текущий вызов, а следующий может быть крупнее, и человек доплачивает дважды. ⚠ **НЕ однострочник, и объявлять его дешёвым было бы ошибкой** (зона дешевизну не подтвердила): новая величина · **ПЕРЕИМЕНОВАНИЕ поля** — `shortfall_micro_usd` станет ложным именем, кандидат `top_up_micro_usd` · минор `StreamVersion` 1.3→1.4 · зеркало словаря у платформы · пере-снятие пина белого списка кадра `ceiling`. ⚠ Построенное поле НЕ ложно, оно у́же: закрывает вызов, а не следующий шаг | бэкенд+платформа | скоро | новая величина + переименование + минор потока | **D39.203**; тензия п.(3) против п.(4) заказа найдена зоной движка | -| 295 | ⛔ **СНАЧАЛА ПОДАТЬ ПОДПИСАННЫЙ КАНОН В ПРОГОН — только потом мерить точность чекера и решать про гейт.** Живая дыра приоритета №1 владельца («100% консистентность») — НЕ порог и НЕ флаг: канон из 53 подписанных терминов **не подключён к стенду**, весь замеренный дрейф — дрейф С ОТКЛЮЧЁННЫМ каноном, а там, где его подключали, консистентность 99.3–100%. ⇒ мерить полноту чекера на прогоне без канона значит мерить не то. **Порядок:** (1) канон в прогон · (2) пере-замер точности/полноты (строка **12**, прежний замер порочен — класс одного иероглифа не имел ни одного положительного примера) · (3) решение владельца по `gates.glossary.postcheck_gate`. ⚠ Владелец 05.09: «если он ложно положительно будет стрелять это плохо, очень плохо» ⚠ **ПОЛОВИНЫ НАЗВАНЫ 06.09 по ревью напарника — прежде тут стояло «назвать или отдать», и это переезжало бы следующей смене той же инерцией.** **(а) Полигон/владелец:** подать канон в стенд-книгу — это ДАННЫЕ (сид-YAML либо решения `bank-apply`) ПЛЮС платный прогон под санкцией; у бэкенд-сессии нет ни книги, ни стенда, ни денег, поэтому половина её не является. **(б) Бэкенд — только ВОПРОСОМ, а не задачей:** умеет ли сид-путь нести подписанный статус; если нет — это пинг оркестратору, и тогда появляется бэкендовая работа. ⇒ зона ведущая — полигон. | полигон (бэкенд — по вопросу) | скоро | подача канона + замер | **D39.205**, D39.198 п.3-4, строка 12 | -| 296 | **ТОЧЕЧНАЯ ПЕРЕГЕНЕРАЦИЯ ПО ПРОМАХУ ГЛОССАРИЯ — направление владельца 05.09 («или флагать, или перегенерировать проблемный участок»), работы сегодня НЕТ.** Актуаторы ремонта — только `RepairLatinResidue` и `RepairBrokenWord` (`backend/internal/pipeline/repair.go`, греп `defaultRepairClasses`); `glossary_miss` нет ни там, ни в `knownRepairClasses`. Сегодняшние лекарства не точечные и обе дороги: удержать ВЕСЬ фрагмент (гейт) либо править глоссарий с `--resnapshot`, то есть ПЕРЕ-ОПЛАТИТЬ книгу. ⇒ заказ: `glossary_miss` как класс-актуатор — перегенерация участка с подписанной формой. ⚠ Гейтится строкой **295**: без замера точности перегенерация по ложному срабатыванию перепишет верный текст | бэкенд | когда-нибудь (после 295) | новый класс актуатора + пост-инвариант | **D39.205** | -| 297 | ✅ **ПЕРВАЯ ПОЛОВИНА ИСПОЛНЕНА ЛЕНДИНГОМ 06.09 (`2f65d1d`, акт `D39.210`): словарь получил четвёртое значение `delimited`**, и spine-EPUB вместе с `\f` в txt больше не выдаются за слово формата. ⛔ **ВТОРАЯ ПОЛОВИНА ТЕПЕРЬ ОБЯЗАТЕЛЬНА, А НЕ ЖЕЛАТЕЛЬНА:** временное правило платформы «`declared` вести как `none`» после лендинга начинает ОТНИМАТЬ ползунок глав у книг, чья структура объявлена настоящим `nav`/NCX — то есть молча недодавать продукт. ⚠ **Якоря прежней редакции этой строки указывали на текст, который пак УДАЛИЛ, а якорный линт этого НЕ ВИДЕЛ** — они были без токена, файл длинный, адрес «разрешался». Живая рабочая строка протухла молча; класс несёт строка **306**, и это его первый пойманный случай в рабочей строке, а не в архиве. ⚠ **Тело прежней редакции СНЯТО 06.09, а не оставлено под шапкой** — оно цитировало рекламу «how much the chapter cut can be trusted» как живую улику, а пак её УДАЛИЛ (`grep -c` → 0), и три его якоря целили в текст, которого нет: словарь уехал, а `:94-95` попал в структуру, введённую дофиксом. То есть строка утверждала про себя, что она первый пойманный случай «якорь протух молча», и одновременно продолжала им БЫТЬ; поймал это строитель пака грепом, линт был зелён. **Что стало вместо снятого:** словарь живёт на `backend/internal/chunk/ingest.go:125-149`=`WHICH PATH drew the chapter boundaries` — четыре значения, и первая же строка комментария теперь говорит про ПУТЬ, а не про доверие. Прежняя двусмысленность («поле отвечает на провенанс, а рекламирует доверие») **устранена паком, а не описана** | бэкенд+платформа | скоро (структурный пак) | недостающее значение на проводе, и `declared` означает ТОЛЬКО объявленную форматом структуру глав | **D39.202**, D39.205 | -| 298 | ⛔ **`unit_resolutions` КЛЮЧЕВАНЫ ПОЗИЦИЕЙ, И ЛЮБОЙ ПЕРЕКРОЙ ИХ СНОСИТ ЦЕЛИКОМ.** Ключ `(book_id, chapter, unit, wave)` позиционен по построению, и миграция это прямо объявляет: «keyed by the ENGINE's own ordinals» (`platform/internal/pgstore/migrations/00015_seam_ceiling_and_units.sql:50-56`); событие `unit_done` несёт номер главы и ординал юнита, синк пишет их как есть (`platform/internal/pgstore/sink.go:249`). Потому при перекрое платформа ОБЯЗАНА удалять решения — иначе они перевесятся на чужую главу. Сегодня цена нулевая: решения есть только у стенд-книги, и это окно закрывается с каждой новой платной книгой. ⇒ разрешать `(chapter, unit)` в идентификатор ПРИ ПРИЁМЕ события, пока дерево у платформы на руках, и хранить идентификатор. Платформенная половина структурного пака: миграция плюс синк. ⚠ Этой строкой НЕ закрывается одноразовая перечеканка всех id при смене смысла `cutTag` — это другой предмет и другая цена | бэкенд+платформа | скоро (структурный пак) | решения переживают перекрой, не переклеиваясь на чужую главу | **D39.202** | -| 299 | ⛔ **ИМЯ В GO-КОММЕНТАРИИ, КОТОРОЕ НИ ВО ЧТО НЕ РАЗРЕШАЕТСЯ, — И НИЧТО ЭТОГО НЕ ЛОВИТ.** ⭐ **ЗАМЕР 05.09, полностью меняющий форму ДОРОГОЙ половины (той, что сверяет имя с каталогом мутаций): она обязана писать ФАЙЛ, а не читать `stdout`.** Полный прогон каталога дал: несущих верхнеуровневых тестов **189** из 1213 тест-функций движка (**15,5 %** батареи; ⚠ испр. 06.09 автором замера: было «194 / 16,0 %» — его парсер резал вывод по запятой, а пять подтестов несут запятую В ИМЕНИ, и круглые «16,0 %» получились именно из пяти фантомов. ⚠ Числитель и знаменатель разной природы: 1213 считает только `^func Test`, а один из 189 — `Fuzz`; честно 188/1213 либо 189/1219, но не 189/1213), и **139 записей из 197 пинятся РОВНО ОДНИМ тестом** — то есть краснота атрибутируется однозначно, и долговременная запись «какие тесты несущие» реально получается. ⛔ **Но тул обрезает список имён на четырёх и печатает `+N more` — так усечены 9 записей из 197, и механизм, читающий `stdout`, насчитал бы 178 вместо 194 И НЕ УЗНАЛ БЫ ОБ ЭТОМ.** Это тот же класс «прибор ответил на свой вопрос»: величина ВЫЧИСЛЯЕТСЯ сегодня, но в поток приезжает УСЕЧЁННОЙ. ⇒ вход механизма — `-logs`, не вывод. Точный список имён воспроизводится пере-прогоном каталога с `-logs`; сохранять его отдельным артефактом не нужно. Два живых носителя, найдены верификацией 05.09 (`D39.207` п.3): **(а)** `backend/internal/runevents/runevents.go:187`=`not to a screen` цитирует **СТАРЫЙ** путь — `docs/BACKEND_MONEYSTOP_SESSION_PROMPT.md`, строка 78 (записано БЕЗ формы якоря намеренно: это УЛИКА мёртвой ссылки, а не ссылка; в форме якоря линт вечно краснел бы на предмете самой записи) — и удалён именно он (промт уведён в архив коммитом `f71c4dc`, тем же, что писал акт), а цитируемая фраза ЖИВА в архивной копии и стоит там на строке **82**. ⚠ **Испр. 06.09: клауза была заландена ПЕРЕВЁРНУТОЙ** — называла удалённым архивный файл, который цел, и приписывала комментарию цитату, которой в нём нет. Механика ошибки записана отдельно, она повторяемая: сплошная замена строки якоря при пере-наведении попала в ОПИСАНИЕ дефекта, где тот же путь был УЛИКОЙ, а не ссылкой, и превратила описание поломки в описание её отсутствия. Нашёл верификатор `textmachine-main-e6` контролем закрытия своих же находок; ⚠ приёмочный столбец строки при этом сформулирован ВЕРНО и поймал бы дефект независимо от прозы — то есть major в описании, не в гейте; **(б)** `backend/internal/config/internal_call.go:11`=`builds a Stage outside the loader` и `backend/internal/pipeline/live_reprobe_test.go:14`=`the single-egress guard` называют сторожами тесты `TestSyntheticStageSeamIsSingle` и `TestProviderEgressSeamIsSingle`, которых в дереве НЕТ — инварианты при этом реально сторожатся вет-анализаторами `StageSeam`/`EgressSeam` (`backend/internal/archguard/archguard.go:80,377`=`StageSeam, RequestSeam, EgressSeam`), то есть гарантия цела, а назначенный ей сторож ВЫДУМАН. Замер верификатора: из 2026 упомянутых в Go имён `Test…` определены 2012; из восьми неразрешающихся четыре — не дефекты (надгробия и иллюстрация), два — мелочь, два — эти. ⇒ **дешёвая половина открытого вопроса `D39.202` п.9: не «доказал ли каталог, что названный тест умеет падать» (дорого, требует интеграции с `tmmutate`), а «РАЗРЕШАЕТСЯ ли названное имя вообще» — это греп, и сегодня он находит два дефекта.** ⚠ `counts.py --lint` этого класса не видит по построению: он читает доки, а не код. ⚠⚠ **ДВА ПРАВИЛА, БЕЗ КОТОРЫХ ГЕЙТ ВЫКЛЮЧАТ НА ВТОРОЙ ДЕНЬ** (принесены верификатором вместе с находкой): **(1)** разрешением считается и ПРЕФИКС — доки и комментарии цитируют имя усечённым, как греп-цель; **(2)** НАДГРОБИЯ не дефект — комментарий, прямым текстом говорящий «удалён/заменён», законен, как и иллюстративное имя в примере. Замер, обосновывающий оба: из восьми неразрешающихся имён СЕГОДНЯ четыре — надгробия и иллюстрация, два — усечение в шапке над функцией, и лишь два — настоящие выдуманные сторожа. Гейт без этих правил краснеет 8 из 8, то есть врёт вчетверо, и его погасят — ⚠⚠ **и ЗАМЕР 06.09 показал, что для указателей `путь:строка` в Go арифметика ХУЖЕ, а потолок дешёвой половины НИЖЕ, чем считалось.** Всего таких указателей **36**; настоящий дефект среди них **ОДИН** (`runevents.go:187`, уже назван выше). Остальное: **5 целят ВНЕ репозитория** (стандартная библиотека Go, `yaml.v3`, jieba) — внутрирепозиторный линт их проверить не может в принципе; **~7 разрешаются НЕОДНОЗНАЧНО** — голое имя файла имеет от двух до восьми одноимённых кандидатов. ⇒ наивный гейт покраснел бы примерно **двенадцать раз ложно при одном настоящем дефекте**. ⛔ **ДВА правила записать ДО заказа, иначе гейт врёт впятеро и его выключат:** **(1)** внешняя цель — НЕ дефект (путь, не разрешающийся в дереве и опознаваемый как чужой, исключается); **(2)** ⛔ **у голого имени файла SOUND-ДЕФОЛТА НЕТ — гейт обязан считать его НЕПРОВЕРЯЕМЫМ (skip), а не угадывать.** ⚠ Прежняя редакция этого пункта предлагала конвенцию «сперва каталог цитирующего файла, затем модуль, затем корень» — **и она ОПРОВЕРГНУТА 06.09 её же автором**: для дока, цитирующего КОД, каталог цитирующего файла систематически неверен, потому что рядом с доком лежат другие ДОКИ. Контрпример — `PROGRESS.md:71` → `README.md:95`: конвенция даёт `docs/README.md` (41 строка) и вердикт «протух», а автор имел в виду `backend/README.md`, где строка 95 **та же, что в минуту написания**. В дереве `README.md` четырнадцать штук. ⇒ гейт с конвенцией краснел бы именно на ЖИВЫХ якорях. Хочешь проверяемости — пиши путь или токен. ⚠ И третье, важнее обоих: **НИ ОДИН из 36 не несёт токена**, поэтому ДОРОГАЯ половина упирается не в инструмент, а в то, что сверять нечего; дешёвая остаётся верным первым шагом, но её потолок теперь измерен — **один дефект на тридцать шесть**. а гейт умирает не отключением, а вытеснением из привычки (`D39.202` п.3-бис) | бэкенд | скоро | грепом: имя `Test…` и `<док>.md:<строка>` в Go разрешаются, иначе красно | **D39.207**, D39.202 | -| 300 | ⛔ **РЕПО-ШИРОКИЙ СТОРОЖ НЕ ДОТЯГИВАЕТСЯ ДО СОСЕДНЕГО ВОРКРИ НА ДРУГОЙ ВЕТКЕ — и стенд от этого УЖЕ СГНИЛ.** ⚠ Замер 05.09, вторая половина: снять пин манифеста стенд-конфигами удалось для **ОДНОГО исходника из восьми**; семь падают, и ни одно падение не про структурный пак. Причины — ретированные в `main` вещи, живые в дереве `polygon`: плейсхолдер `{{genre}}` (ретирован `D39.138` п.2в) — в моём дереве `grep -rln '{{genre}}' backend/prompts/` ПУСТ, в соседнем живёт в ШЕСТИ файлах промтов, и падают на нём 6 конфигов из 8; поля `stm_depth`/`overlap_tokens`, которых больше нет в `config.ContextAssembly` — 1 из 8; ключи `mined_delta:`/`mined_rejects:` (ретированы `D39.156` п.3) — **17 конфигов из 31**. ⭐ **Тест `genre_retired_test.go:46` предсказал этот случай дословно** («should be caught by the repository that retired it, not by a paid run») — и поймали его действительно бесплатно, но **сторож не дотянулся до соседней ветки**, где ретированное живо. ⇒ общая форма дефекта: ретирование, проведённое репо-широким гейтом, НЕ распространяется на воркри другой ветки, и стенд тихо остаётся в прошлом. **ЧАСТНЫЙ СЛУЧАЙ ТОГО ЖЕ КОРНЯ — ДАННЫЕ ПАР-ПАКА В ДВУХ ВЕТКАХ.** Замер бэкенд-сессии 05.09 по 31 конфигу `book.yaml` стенда 蛊真人: у **20** `langpack_root` указывает в СОСЕДНЕЕ РАБОЧЕЕ ДЕРЕВО `/home/ubuntu/projects/textmachine` — а оно на ветке **`polygon`**; у 9 — в `main`; 2 не объявляют его вовсе. Пока каждая ветка собирается из своего дерева, расхождения не видно. ⚠ **Структурный пак (`CHAPTER_STRUCTURE_SESSION_PROMPT.md`) выносит `marker`/`units` из `zh-ru/heading.txt` в данные ИСТОЧНИКА и учит `parseHeading` ОТВЕРГАТЬ эти ключи с переходным сообщением** ⇒ старый файл, оставшийся на `polygon`, станет невалидным, и двадцать конфигов не загрузятся вовсе (загрузка пар-пака FAIL-LOUD). **Выстрелит НЕ при лендинге в `main`, а в момент, когда полигон вольёт `main` в свою ветку** — то есть цена назначена чужой зоне и в чужой момент. ⇒ заказ: перед мержем полигон либо снимает `marker`/`units` из своего `heading.txt`, либо переводит `langpack_root` своих конфигов на `main`. ⚠ Второе дешевле и, возможно, правильнее по существу: **каталоги `configs/langpacks` в обоих деревьях сегодня БАЙТ-В-БАЙТ идентичны** (`diff -rq` пуст, sha256 `heading.txt` совпадают), а комментарии в конфигах, утверждающие «`ru/` есть только здесь», ПРОТУХЛИ — класс строки 299. То есть двадцать конфигов смотрят в чужую ветку по причине, которой больше нет | полигон | скоро (до мержа main в polygon) | конфиги грузятся после мержа, либо `langpack_root` переведён | **D39.207** | -| 301 | ⛔ **`--max-units` НЕ УМЕЕТ СКАЗАТЬ «ДОРАБОТАЙ ПЕРЕНЕСЁННОЕ И НЕ НАЧИНАЙ НОВОГО», И ЧЕЛОВЕК ЗА СВОИ ДЕНЬГИ ПОЛУЧАЕТ НЕ ТУ РАБОТУ.** Флаг бюджетирует N НОВЫХ стартов, а carried-юниты (задрафченные прошлым прогоном и не отгруженные) движок допускает СВЕРХ гранта, до N штук: `granted()` их не считает (`backend/internal/pipeline/volume.go:396-407`), и собственный тест движка это фиксирует — под `--max-units 1` при одном carried выходит `Delivered=2, Carried=1` (`volume_test.go:721`). ⇒ прогон, оборвавшийся МЕЖДУ волнами (стоп на подпись банка, деплой, краш), при респауне получает `--max-units = заказ − доставлено`, и движок оплачивает ЧЕРНОВИКИ глав, которых человек НЕ ЗАКАЗЫВАЛ, раньше редактуры заказанных. ⚠ **Это НЕ перерасход** — `--ceiling-usd` держит сумму; ломается ровно обещание «вы купили N»: за те же деньги приходит другая работа. Выразить нужное платформа не может по построению: вычесть carried значит обнулить грант, а ноль для движка = «без границы» (`planVolume` при `MaxUnits <= 0` возвращает `nil`, `volume.go:321`). ⇒ заказ: словарь скоупа обязан различать «сколько НОВЫХ начинать» и «сколько всего допускать». Живая половина **эрраты 03.09-а** (перенос юнита вне гранта, семантика НЕ ратифицирована, слово владельца «подумаем»), но со следствием более острым, чем записано в ноте: там был перерасход единиц, здесь — подмена предмета покупки | бэкенд+платформа | скоро | флагом выражается «ничего нового не начинать»; пин на респауне между волнами | **D39.207** | -| 302 | **РЕЗКА xhtml ПО ЯКОРЯМ `nav`: текст цел, ГРАНУЛЯРНОСТЬ ТЕРЯЕТСЯ.** Массовая форма EPUB — несколько глав в ОДНОМ документе, разделённых якорями, и `nav` объявляет на них отдельные цели. Структурный пак 1 такие цели СХЛОПЫВАЕТ: одна глава вместо трёх, текст не теряется (формулировка бэкенд-сессии 05.09: «текст цел, гранулярность потеряна»). ⚠ **Ложь при этом уже не едет** — тем же паком ратифицировано: схлопнулась хоть одна цель ⇒ книга НЕ `declared`, а `delimited`, плюс счёт `targets collapsed: N` в WARN. То есть провенанс честен, а разрез груб. ⇒ заказ: резать документ по якорям целей. ⛔ **Почему НЕ сделано паком 1 и почему это дорого:** это единственное место, трогающее `extractXHTML`, у которого **четыре пина байт-паритета** (`ingest_test.go:323, 359, 423, 467` — void-теги, несбалансированный ruby, raw-text-элементы, голый амперсанд), и ошибка там ТИХАЯ. Заходить в него в конце пака, ради гранулярности, при живом гейте разреза — плохой размен. ⚠ Строкой закрывается ГРАНУЛЯРНОСТЬ, а не провенанс: продать такую книгу по главам платформа и так не предложит | бэкенд | когда-нибудь (после пака 2) | книга с тремя якорями в одном документе даёт три главы; четыре пина байт-паритета целы | **D39.207** | -| 303 | **НЕ-CJK ПУТЬ ПОСТРОЕН НАПОЛОВИНУ: чанкер безъюнитную грамматику УЖЕ УМЕЕТ, ингест по ней НЕ РЕЖЕТ.** `detectChapterUnit` итерирует `UnitOrdered` и без юнита возвращает 0 ⇒ грамматика вида «Kapitel 12» / «Chapter 12» (маркер + номер, БЕЗ юнита) книгу не режет; при этом `matchHeaderLine` чанкера юнита не требует и на это есть живой тест (`TestStripHeadingGenericLatinMarker`). То есть заголовок такой книги движок умеет СНЯТЬ, но не умеет по нему РАЗРЕЗАТЬ. ⇒ ревью-вопрос проекта «заработает ли пара, которой в репо НЕТ, без правки Go» закрыт для языков С ЮНИТОМ (доказано сквозным тестом `TestANewLanguageCutsFromItsDataFileAlone`: без файла корейская книга — одна глава, с `ko/structure.txt` — три, разница только в данных) и **ОТКРЫТ для языков без юнита**. Это названный ВХОД в пак 2, а не открытие по ходу. ⚠⚠ **ГРАНИЦА ЗАМЕРА, названная самой зоной и записанная здесь в её настоящей силе:** утверждение проверено **ПО КОДУ и ПО ТЕСТУ НА ФИКСТУРЕ**; **живая не-CJK книга через ингест НЕ прогонялась**. «На живой книге» под этой строкой НЕ стоит, и ссылаться на неё как на замер живого поведения нельзя | бэкенд | скоро (вход пака 2) | безъюнитная грамматика режет книгу; замер на живой не-CJK книге | **D39.207** | -| 304 | ⚠ **РИСК NULLABLE ДЕНЕЖНЫХ КОЛОНОК — НЕ ТЕОРЕТИЧЕСКИЙ, А ОТЛОЖЕННЫЙ, и это вскрыла ЛОЖНАЯ ПРИЧИНА в отчёте зоны.** Платформенная зона объяснила чистый `sqlc diff` тем, что новые колонки лежат «в таблицах, для которых sqlc не держит запросов» — **догадка, и неверная**: `queries/credits.sql` и `queries/exports.sql` читают `books`, `chapters` и `runs`. Верная причина: ни один из этих запросов не выбирает `*` и не называет новых колонок, поэтому сгенерированный код не двигается (греп по `*.sql.go` — ноль вхождений). ⇒ **`books` ЛЕЖИТ в мире sqlc**, значит риск NULLABLE денежных колонок наступит на ПЕРВОМ же запросе, который их выберет, — не «никогда», а «пока не спросили». ⚠ Нашла это зона САМА, четвёртым заходом по прямому вопросу владельца «нет ли чего, что ты умолчала»; ни один гейт поймать это не мог — сторожат поведение и форму, а не то, что отчёт о себе ГОВОРИТ (`D39.202` п.9) | платформа | скоро | первый запрос, выбирающий денежные колонки, не роняет генерацию | **D39.208** | -| 305 | ⚠ **`make check` ПЛАТФОРМЫ ПРИ ТАЙМАУТЕ ПАКЕТА ПЕЧАТАЕТ ЗАГОЛОВОК `--- FAILURES ---` И НИЧЕГО ПОД НИМ.** Замер верификатора 06.09: пакет упёрся в дефолтный десятиминутный таймаут (`FAIL … 600.251s`), секция отказов ПУСТА, ни одного `--- FAIL:` — оператор получает «check упал» **без единого имени**. ⇒ «go test вышел ненулём» и «тест упал» — разные события, а прибор их не различает. ⭐ Это платформенное ЗЕРКАЛО урока, ради которого каталог мутаций движка завёл отдельный вердикт `INCONCLUSIVE`: там различение построено, здесь нет. ⚠ Сам прогон, вскрывший это, верификатор объявил **INCONCLUSIVE и в выводы НЕ взял** — он шёл под нагрузкой тринадцати агентов, и приписывать причину «частично настроенное окружение краснит батарею» отказался сам, назвав это той же ошибкой, которую ловит | платформа | скоро | таймаут пакета называет пакет и причину, а не пустую секцию | **D39.207** | -| 306 | ⛔ **СЕМЬСОТ ЯКОРЕЙ БЕЗ ТОКЕНА НЕПРОВЕРЯЕМЫ, И 59% ИЗ НИХ УЖЕ НЕ УКАЗЫВАЮТ ТУДА, КУДА УКАЗЫВАЛИ.** Замер Fable 5 06.09 (выборка 80, seed фиксирован, метод — blame-триаж: коммит последней правки СТРОКИ ДОКА → цель на том коммите → сравнение): цела **31** · уехала **25** · переписана либо исчезла **22** · не судится 2. ⇒ **59% (±11 п.п.)**. ⚠ Линт сверяет по токену 202 и честно печатает «без токена — несверяемы: 780», но ЗАГОЛОВОК «0 проблемных якорей» читается как «всё цело» — прибор отвечает на свой вопрос, а читают его как ответ на другой (`D39.202`). ⚠ **Дрейф сосредоточен там, где он ОЖИДАЕМ:** 34 из 47 сдвинувшихся — в ЗАМОРОЖЕННЫХ отчётах, чьи тела улика по `D23.3` и обязаны описывать дерево НА ДАТУ; их чинить НЕЛЬЗЯ, им нужен штамп HEAD в шапке. **Опасны 13 в ЖИВЫХ носителях**, и часть из них — в ШАПКЕ журнала, то есть в первом, что читает сессия. ⇒ заказ, тремя шагами и без велосипедов: **(1)** заголовок линта печатает ПОКРЫТИЕ («сверено N · несверяемы M · из них с изменившейся целью — K»), чтобы гейт перестал врать формой; **(2)** ОДНОРАЗОВАЯ механическая миграция тем же скриптом: «цела» → дописать токен автоматически, «уехала» с единственным попаданием → пере-навести, «исчезла» → список на руки; замороженным отчётам вместо пере-наводки штамп коммита и исключение из линта; **(3)** правило «токен при касании» остаётся удержанием линии; **(4)** ⛔ **грамматика УЛИКИ — `path:line@`**, которую линт сверяет через `git show :path`, а НЕ против HEAD (~20 строк в `counts.py`). Без неё автор, цитирующий мёртвый указатель как ПРЕДМЕТ записи, вынужден снимать форму якоря руками — я так и сделал 06.09 и объявил это в тексте, но это подгонка ЗАПИСИ под модель прибора, а не починка модели: **законно как последнее исключение, незаконно как привычка**. Та же форма закрывает и ЗАМОРОЖЕННЫЕ отчёты, которым сегодня штамп HEAD стоит прозой (`research/31`/`32`). ⚠ Сегодня без (2) правка любого дока превращается в игру «бей крота»: каждое касание вскрывает соседний голый якорь. ⚠⚠ **ПЕРЕ-ЗАМЕР 06.09 ГРАММАТИКОЙ САМОГО ЛИНТЕРА — МАСШТАБ ОКАЗАЛСЯ В РАЗЫ МЕНЬШЕ, И ЭТО МЕНЯЕТ ЗАКАЗ.** По 117 живым докам: **214 якорей с токеном** (это и есть те, про кого «0 проблемных») и **1776 без токена**; за конец файла целят 66, однозначно разрешаются 9, и семь из девяти — ВНЕШНИЕ цитаты (стандартная библиотека Go, чужой фронтовый код). ⇒ **настоящий внутрирепозиторный протухший якорь ОДИН** (испр. 06.09 автором замера): `docs/architecture/05-decisions-log.md:21`=`Эррата 28.08-и` — **в ШАПКЕ журнала, которую сессия читает первой**; цель нашлась `git log -S` по тексту якоря и пере-навёдена с токеном. ⚠ **Второй кандидат (`PROGRESS.md:71` → `README.md:95`) оказался АРТЕФАКТОМ РАЗРЕШЕНИЯ ИМЕНИ, а не дефектом** — и он же служит уликой к правилу (2) строки 299. ⭐ **Дешёвый метод для ведра «исчезла», исполненный, а не описанный:** `git log -S'<текст якоря>' -- <док> | tail -1` даёт коммит, ВВЕДШИЙ якорь; `git show <коммит>:<цель>` — что стояло в ту минуту ДОСЛОВНО; `git grep` — сегодняшний адрес. Угадывания нет ни на одном шаге. ⛔ **ОПИСАНИЕ ЧУЖОГО МЕТОДА В ЭТОЙ СТРОКЕ БЫЛО ЛОЖНЫМ — СНЯТО 06.09.** Абзац писал, что «59 % на выборке 80» получены наивным резолвингом (голое `mining.go:40` из подкаталога ищут от корня, не находят, объявляют мёртвым). **Наивный резолвинг — метод АГЕНТСКИХ чисел** («42 %», «19 из 32 мертвы»), и опровергнуты им именно они; тем же способом автор пере-замера получил «31 мёртвый из 36» и не понёс их, потому что стал сверять расхождение. Замер Fable 5 устроен иначе и так же описан в ГОЛОВЕ этой строки: берутся только ЗОННО-ПРЕФИКСНЫЕ пути, `git blame` даёт коммит последней правки СТРОКИ ДОКА, `git show <тот коммит>:<цель>` — цель на ту минуту, и сравнивается СОДЕРЖИМОЕ с HEAD. ⇒ строка противоречила сама себе: голова описывала blame-триаж, хвост объявлял его наивным резолвингом. **Класс строки 299, только внутри бэклога.** ⚠ **ДВА ЧИСЛА ОТВЕЧАЮТ НА РАЗНЫЕ ВОПРОСЫ, и потому ни одно не опровергает другое.** Пере-замер грамматикой линтера спрашивает «указывает ли якорь в СУЩЕСТВУЮЩУЮ строку HEAD и совпадает ли токен» — ответ: 214 с токеном, 1776 без, за конец файла 66, однозначно разрешаются 9, настоящий внутрирепозиторный протухший ОДИН. Замер blame спрашивает «изменилось ли СОДЕРЖИМОЕ цели с той минуты, когда строка дока была написана» — ответ: ~59 % на выборке 80. Первый вопрос про HEAD, второй про ДРЕЙФ; строка обязана нести оба, а прежняя редакция вычитала одно из другого. ⚠⚠ **И вопрос HEAD слеп ПО ПОСТРОЕНИЮ к тому самому якорю, ради которого строка заведена:** якорь шапки журнала был написан голым — `seeding.go:143-153`, без слэша, — а `docs/scripts/counts.py:592`=`"~" in rel or "/" not in rel` относит такую форму к «неразбираемым» и пропускает МОЛЧА, ДО всякой проверки файла. ⚠ **Испр. 06.09 по ревью Fable 5: файл НЕ переименовывали** — `seeding.go` жив и сегодня (128 строк), а `bankmaterialize.go` ДОБАВЛЕН `6ec9f8a` 29.08, и в него ПЕРЕЕХАЛ код. Прежняя редакция этой строки писала «переименовали», и следствие «ветвь «файла нет» не выстрелила» было лишним: голое имя до той ветви не доходит по построению. Прибор не видел ровно того случая, с которого начался заказ, — и «0 проблемных» был честен про свой вопрос и слеп про этот. ⚠ И одно слово в этой строке названо неточно: пере-замер сделан ГРАММАТИКОЙ линта (его правила разрешения путей и целей), но не самим линтом и не сверкой токенов — у голых якорей токенов нет — этот якорь линт не видит по построению, и два абзаца строки описывают РАЗНЫЕ приборы одним словом. ⚠ И у метода есть ложные срабатывания: две находки этого же прохода я проверил руками — одна («`STACK.md:11` исчезло») оказалась ЛОЖНОЙ, цель жива и точна | оркестратор | скоро | линт печатает покрытие; голых якорей в ЖИВЫХ доках нет | **D39.202** | -| 307 | ⛔ **СПАН ПОД ПОДПИСЬЮ «СКОЛЬКО ЗАКАЗАНО» — ЛОЖЬ ЯРЛЫКОМ, И ЧЕСТНАЯ ФОРМА ДРУГАЯ.** Для заказа, выраженного ЗНАКАМИ, `Run.ordered_chapters` несёт не заказанное, а **СПАН** — сколько глав заказ ЗАТРАГИВАЕТ, считая главу затронутой независимо от того, куплена ли она целиком (`pricing.QuoteUnits` ставит `Chapters: max(chapters, 1)`, вызывающий передаёт `chaptersSpanning`, и сам код называет это «coarser of the two figures»). ⚠ **Замер зоны:** заказ на ОДИН юнит из четырёх в первой главе даёт `1` — **сто процентов завышения на самом дешёвом заказе**, то есть на том, которым сервис пробуют впервые. ⇒ число под именем «ordered chapters», превышающее заказанное, — ложь ярлыком, сколь угодно последовательная. ⭐ **Разбор, снявший спор:** нужда, которую зона защищала («видно, докуда дошли деньги»), настоящая, а носитель неверный — «докуда» есть **ПОЗИЦИЯ** («достигает главы N»), а не **КОЛИЧЕСТВО** («2 главы»), и позиция у платформы УЖЕ ЕСТЬ (`Quote.ThroughChapter`, `BookOrder.ThroughUnitID`). ⚠ Спан ≠ позиция для заказа-продолжения: спан считает затронутые от текущей точки, позиция — ординал. ⇒ **честная форма:** `ordered_chapters: null` для символьного заказа (зеркало `delivered_chapters: null` — «заказано не в главах») + аддитивно `ordered_characters` (эхо запроса) + позиция ординалом, если экрану нужно «докуда». Это смена формы (поле становится нуллабельным) ⇒ минор. ⚠ **Цена смены почти пуста и это ЗАМЕРЕНО:** `ordered_chapters` вошёл в канон только `75ae6f0`, до него в файле НОЛЬ вхождений — клиент 0.10.0 поля не видел никогда, а `ceiling_chapters` тот же минор уже отвергает с 400. ⚠ Поведение менять НЕ требуется: политика «заказ выражен в знаках и меряется в них насквозь» верна и остаётся. До лендинга формы канон описывает ДЕФЕКТ с ⛔-пометкой, а не дизайн | бэкенд+платформа | скоро | `ordered_chapters` нуллабелен, размер заказа эхом, позиция отдельно | **D39.208** | -| 308 | **ВИД ПРОГОНА ЗАКОДИРОВАН НУЛ�ём, И ЭТО ЕДИНСТВЕННАЯ ЕГО МЕТКА ВО ВСЕЙ ПЛАТФОРМЕ.** Явного признака ре-прохода у `LiveRun` НЕТ: `Resnapshot` не годится — он ставится и ОБЫЧНОМУ продолжению после правки банка, а валидация `OrderedChapters == 0 && !Resnapshot` читается «ноль допустим только под пере-снапшот», то есть ре-проход ⇒ resnapshot, а не наоборот. ⇒ **вид прогона различается ЗНАЧЕНИЕМ денежного поля**, и держится это на двух вызовах `max(n, 1)` (`pricing.QuoteUnits`, `runs.chaptersSpanning`). ⚠ **Опасность растёт после лендинга формы заказа** (строка 307): снаружи символьный заказ станет `null`, и единственное место, где `max(n,1)` что-то значит, уходит ВНУТРЬ — следующий читатель колонки (отчёт, CLI) напечатает спан под старым словом и не узнает об этом. ⇒ заказ: **явный признак вида** (`RePass`) вместо кодирования вида нулём. ⛔ **Рантайм-пояса `== 0 && OrderedUnits == nil` ставить НЕЛЬЗЯ** — символьный заказ не может записать ноль ни при каких данных, а гейт от несуществующего состояния завтра прочтут как свидетельство, что состояние бывает. Честная защита до рефакторинга — **ПИН инварианта** «символьный заказ на один юнит пишет в колонку 1, никогда 0» (замер у зоны уже есть — сто процентов завышения на самом дешёвом заказе; норма `D39.209` требует превратить замер в пин) плюс одно предложение в комментарий колонки. ⚠ Это рефакторинг в ДЕНЕЖНОМ коде без дефекта сегодня — отдельным паком, не минором формы заказа | платформа | когда-нибудь (после строки 307) | вид прогона читается признаком, а не значением денежного поля | **D39.208** | -| 309 | ⛔ **ГЕЙТ ВЕРСИИ КОНТРАКТА СВЕРЯЕТ ЧИСЛА, А НЕ ФОРМЫ — И ПОТОМУ НЕ ВИДИТ ГЛАВНОГО РАСХОЖДЕНИЯ.** `TestTheAnnouncedContractVersionIsTheOneTheCanonRatified` сверяет константу сборки с `info.version` канона. Пока эти два числа равны, гейт ЗЕЛЁН — **даже если провод и документ описывают РАЗНЫЕ формы**. Замерено 06.09 трижды за сутки: канон 0.11.0 объявлял полосу «in chapters», а сборка слала юниты; обещал `ordered_chapters: 0` для символьного заказа, а приезжал спан 2; перечислял три значения словаря, а движок слал четыре. **Ни одно из трёх гейт не покраснил**, потому что число совпадало. ⇒ заказ: сверять ПОЛЯ схемы с проводом, а не только версию. ⭐ **Дешёвая форма названа Fable 5 и уже наполовину оплачена нормой:** тест платформы пишет РЕАЛЬНЫЕ ответы в `examples/*.json` (по действующему правилу «фикстуры снимать реальным бинарём»), канон несёт их в `examples:`, линт сравнивает — тогда фраза «both report 0» умерла бы о файл примера, а не о верификатора через сутки. Прозу это не ловит, ЗНАЧЕНИЯ — ловит. ⚠ Вторая половина той же нормы — **авторство**: утверждение канона о ЗНАЧЕНИИ пишет ЗОНА из своих пинов и называет пин в сообщении коммита; оркестратор ратифицирует текст, а не сочиняет его. Три сегодняшние лжи в каноне написаны тем, у кого не было прогона | оркестратор+платформа | скоро | поля схемы сверяются с проводом порождёнными примерами | **D39.208** | - -| 310 | ✅ **ИСПОЛНЕНО ЛЕНДИНГОМ 06.09 — акт `D39.213`, `201363b`; замерено, что дефект успел испортить числа приёмки: общий лог дал лишний пакет и СПРЯТАЛ ДВА СКИПА.** ⛔ **БАТАРЕЯ ПРИЁМКИ УМЕЛА ВЫДАТЬ ЛОЖНУЮ ЧИСТУЮ СПРАВКУ О ТОМ, ЧЕГО НИКТО НЕ МЕРИЛ.** `make check` пишет лог в ФИКСИРОВАННЫЙ путь `platform/.check.log` и удаляет его при зелени. Два прогона в одном каталоге — а 06.09 они шли — молча уничтожают улику друг друга: грепу нечего читать, и батарея печатает **«--- every test ran: no host condition was missing ---»** при ПЯТИ скипах. ⚠ **Наблюдено, не выведено** (прогон зоны v16: трижды `grep: .check.log: No such file or directory`, следом чистая справка, `MAKE-EXIT=0`). Код возврата остаётся нулём, потому что статус берётся от `go test` ДО грепов, ⇒ наружу выходит СПРАВКА О НЕИЗМЕРЕННОМ, а это хуже отсутствия справки: она закрывает вопрос, которого никто не задавал. **Девятая форма ложной зелени** (`D39.202`) в самом приборе приёмки. ⇒ заказ: батарея ПАДАЕТ ГРОМКО, если лога нет (либо имя файла уникально на прогон); мутация «снять лог» обязана краснить `gates.TestTheBatteryNamesEveryHostConditionItsTestsRead`, а не проходить. ⚠ Обходной путь на сегодня, применённый обеими сторонами: числа снимать своим `go test ./... -race -count=1 -v` в файл ВНЕ каталога зоны, куда чужой прогон не дотянется. ⭐ Нашла платформенная зона на СЕБЕ и намеренно НЕ чинила в составе дофикса, чтобы не смешивать предметы посреди лендинга | платформа | скоро | лог не найден ⇒ батарея красная, а не «всё прогналось» | **D39.212** | - -| 311 | **ПОПРОГОННЫЙ ЛОГ БАТАРЕИ КОПИТСЯ: КАЖДЫЙ УПАВШИЙ ПРОГОН ОСТАВЛЯЕТ СВОЙ ФАЙЛ НАВСЕГДА.** Прежнее ФИКСИРОВАННОЕ имя само себя ограничивало — сколько бы прогонов ни падало, оставался ОДИН несвежий файл, и следующий его перезаписывал. Починка `D39.213` сняла коллизию вместе с этим свойством: `.check.log.` не убирает никто. ⚠ **Замер:** к утру 06.09 в корне зоны лежали ЧЕТЫРЕ таких файла нулевого размера от прибитых прогонов и стаб-проб (удалены зоной как её мусор). ⛔ **Опасность НЕ в коммите** — `platform/.gitignore:3`=`.check.log*` их держит, проверено. Опасность в том, что через месяц человек не отличит «мусор от прерванных прогонов» от «лога, который рецепт НАРОЧНО сохранил при падении, чтобы его прочли», — а второе законная и нужная функция, и она тонет в первом. ⇒ заказ: перед прогоном убирать логи, чей PID УЖЕ МЁРТВ (`[ -d /proc/$p ] || rm -f`). ⛔ Голый `rm -f .check.log.*` ставить НЕЛЬЗЯ: он снова снесёт улику параллельного прогона — ровно тот дефект, из которого всё и выросло. ⚠ Привязка к `/proc` линуксовая; зона на Linux, но это оговорка, а не мелочь. ⭐ **Названо ЗОНОЙ про собственную починку уже ПОСЛЕ того, как я её принял** — то есть ценой не приёмки, а совести | платформа | когда-нибудь (следующее касание прибора) | мёртвые логи убираются, живые не трогаются | **D39.213** | - -| 312 | ✅ **ИСПОЛНЕНО ЛЕНДИНГОМ 06.09 `e4211d4`** — счётчик `backend/internal/chunk/ingest.go:86-99`=`TOCUnreadable counts tables of contents`, вынесен в ноты рефлексионным сторожем; пин `TestADeclaredTableOfContentsThatCannotBeReadIsCounted`, пять подтестов, три дороги проверены мутацией порознь, а «не заявлено» и «прочли, цели висят» держатся отдельными случаями. ⚠ **Последняя миля НЕ пройдена и названа зоной прямо:** нота идёт в лог ДВИЖКА (`r.Log.Warn`), а платформа читает `events.jsonl` — то есть тревога есть, а увидит ли её человек, не показано (Д-3, открыт). ⛔ **ЗАЯВЛЕННОЕ, НО НЕЧИТАЕМОЕ ОГЛАВЛЕНИЕ ПРОВАЛИВАЛОСЬ МОЛЧА — И ЭТО САМЫЙ ДЕГРАДИРОВАННЫЙ СЛУЧАЙ КЛАССА, КОТОРЫЙ ТОТ ЖЕ ПАК И ЛЕЧИЛ.** Книга ЗАЯВИЛА оглавление (`properties="nav"` в манифесте либо `toc` в spine), движок не смог прочесть или разобрать эти байты — и тихо падает до spine, отдавая `delimited`, то есть продажу ПО ЗНАКАМ, без единого слова о причине. ⚠ **Улики на момент находки** (адреса намеренно БЕЗ якорей: код починен `e4211d4`, и якорь целил бы в строку, которая дефекта больше не показывает): ошибка чтения глоталась в `ingest.go` обеими ветвями — nav и NCX, — провалившийся разбор возвращал метки, а счётчика не было вовсе (греп по `unreadable`/`tocUnread` в `chunk/` давал пусто). ⛔ **`toc_unresolved = 0`, потому что целей НОЛЬ** — прибор снова честно отвечает на свой вопрос, а читается это как «всё разрешилось» (`D39.202`). ⇒ тревога, построенная для класса M-2 («часть целей не разрешилась»), НЕ покрывает случай «оглавления не прочли вообще». ⇒ заказ дешёвый: один счётчик в `Document` («declared table of contents that could not be read»), который рефлексионный сторож сам вынесет в `IngestNotes()`. ⭐ **Названо строителем в письме о вычитке и НЕ починено** — он сам нашёл это, только когда я спросил про сомнения. **Улика к норме: находка, живущая в письме, носителя не имеет и исчезает** — ровно то, что зона платформы сказала про находки без ряда | бэкенд | скоро | заявленное нечитаемое оглавление называет себя, а не тонет в `delimited` | **D39.202** | - -| 313 | ⛔ **КАТАЛОГ МУТАЦИЙ ДОКАЗЫВАЕТ, ЧТО МУТАЦИЯ СУЩЕСТВУЕТ, А НЕ ЧТО ОНА ЛОВИТСЯ.** Из **211** записей каталога регулярно гоняются единицы (в паке структуры глав — 14, целящие в изменённое поведение); остальные проверяются только на ЖИВОСТЬ ЦЕЛИ грепом. ⇒ зелёный каталог говорит «посадка на месте», а читается как «посадка краснит». **Тот же класс, что `D39.214` п.3: доказано одно, сказано про другое.** ⚠ Носителя у этого НЕ БЫЛО ни строкой, ни рядом — проверено грепом по живому бэклогу 06.09 по прямому вопросу оркестратора; ближайшая строка 252 говорит о ДВУХ конкретных выживших посадках 04.09 и о полном прогоне не говорит ничего. ⭐ **Третий за час случай, когда находка жила только в письме** (первые два — находки платформы без рядов и нечитаемое оглавление строки 312): **находка без носителя не находится.** ⇒ заказ: либо каталог гоняется целиком по расписанию, либо его зелень перестаёт называться доказательством ловли — формулировку выбирает зона, но молча оставлять нельзя. ⚠ Назвал СТРОИТЕЛЬ про собственный пак, единственным из пяти своих сомнений, что закрыл бы ДО продажи ⚠ **Цена полного прогона ЗАМЕРЕНА 06.09, и отсрочка обоснована ею, а не удобством:** 126 записей из 211 гоняют `internal/pipeline` по ~3 минуты ⇒ полный прогон **6+ часов**. При этом 197 непрогнанных — УНАСЛЕДОВАННЫЕ, каждая краснела у заводившей смены. ⇒ это стоячая гигиена, а не крит; зона прямо отказалась изображать закрытие шестичасовым прогоном «вдруг что-то протухло» | бэкенд | когда-нибудь | зелень каталога означает пойманную мутацию, а не существующую запись | **D39.214** | - -| 314 | ⛔ **РАЗРЕЗ ПРОВЕРЯЕТСЯ ТОЛЬКО НА НЕИЗМЕННОСТЬ — НА ПРАВИЛЬНОСТЬ ЕГО НЕ ПРОВЕРЯЕТ НИЧТО.** Ни один гейт, тест или замер не отвечает на вопрос «верны ли ЭТИ границы»: гейт сравнивает «до» и «после», оракул сверяет два прибора движка МЕЖДУ СОБОЙ. ⚠ **Инвариант сохранения доказывает СОХРАННОСТЬ и молчит о КОРРЕКТНОСТИ** — он считает разбиение (каждый читаемый документ либо исключён намеренно, либо ровно в одной группе) и сходится ОДИНАКОВО при верной и при неверной группировке, если та ничего не теряет. ⇒ «инвариант сошёлся на трёх живых книгах» доказывает сохранность, а читается как корректность разреза. Что 71 глава для Kristoff — ВЕРНО, не показал никто; показано лишь, что так говорит его `nav`. **Тот же класс, что `D39.214` п.3: доказано одно, сказано про другое.** ⭐ Назвал СТРОИТЕЛЬ про собственный пак, найдя это в своих же утверждениях, а не в чужих. ⚠ **Измеримая часть ЗАМЕРЕНА 06.09 и расхождения не дала:** «совпадает ли отданный разрез с тем, что книга ОБЪЯВЛЯЕТ» — по трём книгам 193 цели оглавления, **все на уровне документа, ни одной внутрь документа** (Kristoff 71 · isekai 88 · fifty_shades 34) ⇒ там, где объявленное можно сверить механически, оно сходится. **Остаётся ровно некруговая часть: верно ли то, что объявляет сам `nav`** — она требует человеческого суждения и не закрывается ни тестом, ни прибором. ⇒ **строка стоит не как задача, а как признанная ГРАНИЦА** | бэкенд | когда-нибудь | есть носитель, отвечающий «верны ли границы», а не только «не изменились ли они» | **D39.214** | -| 315 | ✅ **ЗАКРЫТА ЗАМЕРОМ 06.09 — ПРОШЛА.** Блокер («промтов пары `en-ru` нет») снят БЕЗ нарушения запрета: у пар-конфига есть ручка `prompts_root` (`backend/internal/config/pair.go:33`=`PromptsRoot string`, проверено мной), и корень промтов-заглушек собран ВНЕ репозитория — в дереве не создано ничего, промт-пака пары как не было, так и нет. **Замер зоны, `tmctl manifest`, EXIT 0, $0:** `structure: declared` · 71 глава / 351 юнит / 356 чанков · `manifest_version` НЕ сдвинут · нумерация плотная 1..71 без дыр и дублей, `number: null` — ноль · id глав уникальны · **`title_raw` на проводе 71 из 71**, настоящие · ценовая проекция на всех трёх уровнях, глав без цены ноль. ⭐ **И то, что видно только на живой НЕ-CJK книге: `heading` пуст у ВСЕХ глав** (шаблона для пары нет), **а `title_raw` заполнен** ⇒ единственное, что несёт название главы для этой книги, — поле, которое построил этот пак. Обоснование §2.5 стало замером, а не доводом. ⚠ Числа — зоны, на её стенде; механизм обхода блокера и чистоту дерева проверил я. ⛔ Прежняя формулировка: **МАНИФЕСТНАЯ ПОЛОВИНА EPUB НЕ ПРОХОДИЛА НИ РАЗУ НА ЖИВОЙ КНИГЕ.** `tmctl manifest` на EPUB владельца не идёт — промтов пар `en-ru`/`ja-ru` не существует, и пак структуры глав чинить это не заказывал. ⇒ `title_raw` на проводе, id глав и ЦЕНОВАЯ ПРОЕКЦИЯ для EPUB держатся **исключительно на фикстурах авторства самой зоны**; книги владельца мерены только на уровне ингеста. ⚠ **Первая же платная EPUB-книга пойдёт по пути, который на живой книге не проходил никогда** — и это ДЕНЬГИ, а не удобство. ⭐ Стоит в отчёте зоны §6, но отчёт не трекер: через месяц его никто не откроет — ровно довод, которым эта строка и заведена | бэкенд+полигон | скоро | манифестная половина EPUB пройдена на живой книге хотя бы раз | **D39.214** | -| 316 | **У ЭРРАТ НЕТ РЕЕСТРА, И ЧИТАТЕЛЬ НОТЫ НЕ МОЖЕТ УЗНАТЬ, КАКИЕ ИЗ НИХ К НЕЙ ОТНОСЯТСЯ, НЕ ПРОЧТЯ ВСЕ.** Замер верификатора 06.09: эррат в шапке **53**, из них 06.09-* — **10**; на `D39.212` их три, на `D39.211` две, на `D39.213` две; длина одной — **929–4020 знаков ОДНОЙ строкой**. ⇒ **чтобы прочесть `D39.212` верно, надо прочесть 7912 знаков эррат при теле акта около 5000 — корректирующего текста БОЛЬШЕ, чем корректируемого**, и цепочка уже глубиной два (`06.09-ж` правит `06.09-г`). ⚠ **Дефект НЕ в объёме правок:** след — это ровно то, ради чего смена стоила своих денег, и все сегодняшние нормы выводимы только из него (что заявлено, кем опровергнуто, чем). Дефект в том, что **у нот реестр есть (`docs/architecture/05-decisions-index.md`), а у эррат нет ничего.** ⇒ дешёвая форма, названная верификатором: строка реестра получает колонку «живые эрраты», `counts.py` её сверяет — тот же класс, что восьмой гард итога регистра: **не помнить, а проверять**. ⚠ **Отложено сознательно, а не забыто:** это седьмая правка прибора за смену, а предыдущие шесть трижды потребовали починки после приёмки; менять гейт на исходе смены — ровно та спешка, которой этот бэклог посвящён | оркестратор | скоро | к ноте один хоп даёт список живых эррат, и его сверяет гейт | **D39.202** | - -| 317 | **У ЧИСЛА, СТОЯЩЕГО В КАНОНЕ, НЕТ ПРИБОРА В РЕПОЗИТОРИИ.** `D39.214` п.6 цитирует замер «сканер по 193 свойствам схем канона, три правила, семь флагов, пять ложных, два настоящих». **Сканер не закоммичен** — проверено грепом 06.09. ⇒ ни «193», ни «семь» не воспроизводимы никем, включая автора. ⛔ **ПОДОЗРЕНИЕ НА НЕПОЛНОТУ СКАНА СНЯТО 06.09 — И СНЯЛ ЕГО ТОТ, КТО ПРИНЁС.** Сначала агент верификатора пере-выполнил три правила по описанию и получил **двенадцать** флагов; это читалось как «зона что-то не досмотрела». Верификатор довёл зацепку до замера сам: **189 свойств, 9 уникальных флагов** — ровно зонные ПЯТЬ ложных плюс `Chapter.number` (настоящая находка, уже диспозиционированная) плюс три `EventStatus.*_reason`, **которые оказались дефектом ЕГО реализации**: правило читало `description` самого поля и не читало РОДИТЕЛЬСКИЙ объект, документирующий все три разом (`docs/architecture/14-api-contract/openapi.yaml:3123`=`unless its own status`). ⇒ **знание там не расщеплено, а централизовано — сказано один раз на три поля, и это лучше, чем трижды.** Семёрка зоны ВЕРНА, пропущенного нет. ⚠ И `OrderOptions.structure` прибор больше не флагует — потому что зона его починила. ⇒ **дефект этой строки — НЕВОСПРОИЗВОДИМОСТЬ числа, а не его неверность**, и срочность соответствующая. ⭐ **Та же форма, что норма «число называет ДЕРЕВО и ПОПУЛЯЦИЮ», только про ИНСТРУМЕНТ:** одноразовый скрипт, давший число в канон, обязан ехать в репозиторий вместе с числом — иначе замер неотличим от утверждения. ⇒ заказ: либо сканер ложится в `platform/` (или `docs/scripts/`) и число пере-снимается им, либо число в каноне помечается как невоспроизводимое. ⚠ Принёс верификатор ПОСЛЕ своего «ок», прямо сказав «это зацепка, а не находка, и опровержением зоны я это не считаю» | платформа+оркестратор | когда-нибудь | число в каноне пере-снимается прибором, лежащим в дереве | **D39.214** | - -| 318 | ⛔ **ПОСТЧЕК БАНКА ОБЕЩАЕТ ЛОВИТЬ СТРАХ ВЛАДЕЛЬЦА И МОЛЧИТ РОВНО ТОГДА, КОГДА ТОТ СБЫВАЕТСЯ.** Комментарий `backend/internal/membank/mempostcheck.go:14-16`=`we injected the wrong dst and the model obeyed it` объявляет, что промах ловит ОБЕ беды — «модель проигнорировала глоссарий» И «мы вложили неверный dst, и модель его исполнила (страх владельца)». Код делает обратное: `present := dstFormPresent(...)`, затем `if present { continue }` — **исполненная неверная строка ПРИСУТСТВУЕТ в выводе, значит промах не пишется**. ⇒ чем послушнее модель исполнила ложь, тем надёжнее прибор молчит; метрика «нет постчек-миссов» означает «банк ИСПОЛНЕН», а читается как «исполнен ВЕРНО». ⚠ Независимое подтверждение в дереве: `docs/experiments/18-editor-wire-probe.md` — «Механизма, который это ловит, в пайплайне нет». ⚠ **Вред реплицирован ДВАЖДЫ на разных проводах и моделях** (`research/24`, транслятор-провод, принято `D39.102`; `experiments/18`, редакторский, принято `D39.108`): неверная строка принята 6/6 и вытеснила верную 5/6. ⇒ немедленно и дёшево — **привести комментарий к тому, что код делает** (правка комментария в хеш не входит); отдельно и дороже — недостающий ДЕТЕКТОР правильности значения. ⛔ Ослаблять `D39.104` НЕ предлагается: закон банка ратифицирован, и доказательств против него нет | бэкенд | скоро | комментарий описывает поведение, и есть носитель у вопроса «верно ли значение» | **D39.202** | -| 319 | ⛔ **ПРИБОР СЛЕПОГО ЧТЕНИЯ ШТРАФУЕТ РОВНО ТО ПОВЕДЕНИЕ, КОТОРОЕ САМ ЖЕ ЗАКАЗЫВАЕТ.** Судимой руке предписано `eval/dovodka/prereg-4axes/stand/editor-p9.md:5`=`Сверяй смысл черновика с исходным текстом` — то есть ОТХОДИТЬ от черновика там, где он искажает оригинал. А блокирующая линза `eval/dovodka/blind-read/PREREG-2-BLIND-READ.md:62`=`точность относительно черновика` меряет верность ЧЕРНОВИКУ, ⇒ мы велим редактору ОТХОДИТЬ от черновика там, где тот переврал оригинал, и меряем его ВЕРНОСТЬЮ черновику. ⛔ **ПРОТИВОРЕЧИЕ КОНСТРУКЦИИ ДОКАЗАНО — ВЕЛИЧИНА ИСКАЖЕНИЯ НЕ ЗАМЕРЕНА, и это разные вещи.** Прежняя редакция строки писала «прибор СИСТЕМАТИЧЕСКИ поощряет якорение» и «отход от черновика записан в ДЕФЕКТЫ»: **испр. 06.09 автором строки** — фраза «Отход от черновика» встречается в сыром судейском массиве ОДИН раз, то есть это наблюдение, а не свойство, и масштаб я выдал за факт, не посчитав. Доказано ровно одно: две бумаги в одном дереве требуют взаимоисключающего. ⇒ вывод замера **ненадёжен ПО ПОСТРОЕНИЮ** независимо от частоты, и величину надо мерить ДО любого следующего решения о тире редактора. ⚠ Задет приоритет владельца №2 («отсутствие выдумок — редактор, сверка с ИСХОДНИКОМ», `D39.198` п.2). ⭐ **Этого довода в отчётах Кодекса НЕТ — он найден консилиумом**, и он сильнее всего, что там написано. ⚠ Обвязка с исходником уже существует в том же дереве (`eval/dovodka/judge-prompts/`), то есть нужен не новый прибор, а ПЕРЕ-ПОДКЛЮЧЕНИЕ готового. ⚠ ⚠ **Три эрраты в носителях замера — ФОРМОЙ БАННЕРА, тела НЕ править** (оба документа заморожены, и пре-рег ценен именно неизменяемостью), и **горизонт у них другой: ПЕРВЫМ касанием полигона, ДО пака починки линзы** — иначе три дешёвые правки будут ждать дорогого пака. Не исполнены ни одна: «правильный ответ по построению — ничья» противоречит собственному тексту отчёта; из §8 пре-рега выпало унаследованное ограничение «опора судьи — черновик, не оригинал»; правило решения готово выдать вывод, который отчёт результата запрещает дословно | полигон | скоро | линза меряет то, что руке заказано, и носители замера не противоречат себе | **D39.198** | -| 320 | **ДВА СОВЕТА ДВИЖКА, КОТОРЫХ ДВИЖОК НЕ ИСПОЛНЯЕТ.** (а) `backend/internal/membank/memseed.go` советует оператору «mark one status: auto», а гард полисемии статус НЕ СМОТРИТ вовсе — условие `a.Src != b.Src || a.Dst == b.Dst || !windowsOverlap(...)`, и совет в пределах одного файла не сработает НИКОГДА. Одна строка плюс тест. (б) `internal/lang/data/``injection.txt` несёт заголовок «НЕПОДТВЕРЖДЁННЫЕ РАБОЧИЕ ВАРИАНТЫ», живой в сборке (`internal/lang/embedded.go:449`), тогда как `membank/memory.go` прямым текстом объявляет «NO ⟨проверить⟩ MARKER, and no fork by status at all» по `D39.104` п.2. ⚠ Правка ДАННЫХ — стоп-мир (`EmbeddedVersion` → `cutTag` → `manifest_key`), поэтому прицепом к паку строки 161, а не отдельным заходом; правка комментария (а) дешева и сегодня | бэкенд | скоро | совет и заголовок описывают то, что сборка делает | **D39.202** | - -| 321 | ⛔ **РЕДАКТОР ПОДБИРАЕТ БАНК БЕЗ ПАМЯТИ О ПРЕДЫДУЩИХ ЕДИНИЦАХ, И ОПРАВДАНИЕ В КОДЕ ЛОЖНО.** Черновая волна передаёт sticky-контекст, редакторская — `nil`; комментарий рядом оправдывает это тем, что единица есть глава либо её часть, «так что внутриглавное окно липкости неприменимо». **Оправдание неверно:** глава РЕГУЛЯРНО делится на несколько правочных единиц (`assignEditUnits` жадно пакует чанки до потолка и закрывает единицу ВНУТРИ главы), а sticky сбрасывается только на границе ГЛАВЫ. ⚠ **ЗАМЕР 06.09 (Fable 5, `tmctl manifest` на `22e079e`, $0):** слайс 25 глав — 57 чанков / 37 единиц / **11 многоединичных глав**; ПОЛНАЯ книга — 2283 главы / 5071 чанк / 4276 единиц / **1962 многоединичных, то есть 86 %**. Прежнее «56 чанков» взято из архивной СИМУЛЯЦИИ, факт 57. ⛔ **И картина «черновик сохраняет — редактор теряет» верна только для СИДОВОГО банка:** на нынешнем стенде все строки mined, базовый банк ПУСТ, черновая волна банка не несёт вовсе, а редакторская — единственная с банком — не переносит между единицами. ⚠ **Экспозиция замерена, дрейф — НЕТ:** теряется 49 банковых строк на 12 единицах, из них у **4** форма перевода уже стоит в черновике (все Confirmed); инцидентов не наблюдено ни одного. ⇒ **сначала мерить на следующем платном прогоне** ($0 по хранилищу), потом строить. ⚠ Теста, фиксирующего нынешний `nil`, НЕТ ⇒ правка это багфикс, а не смена заказанного поведения. ⚠ **Sticky — это множество id БАНКОВЫХ строк, не пересказ повествования**; отчёт Кодекса описал его неверно, и это отдельно опровергнуто. ⇒ предмет: либо передавать, либо привести комментарий к правде — но молча оставлять оправдание, которое разошлось с кодом, нельзя | бэкенд | скоро | редакторская волна либо несёт перенос, либо объясняет отказ верно | **D39.215** | -| 322 | ⛔ **УКАЗАТЕЛЯ ПРИНЯТОЙ РЕДАКЦИИ НЕТ: НЕУДАЧНАЯ ПОВТОРНАЯ РЕДАКТУРА ЗАТИРАЕТ ДОСТУПНЫЙ РЕЗУЛЬТАТ.** ⛔ **ПРОДУКТОВАЯ РАМКА ЭТОЙ СТРОКИ БЫЛА НЕВЕРНА И СНЯТА 06.09 (поправка владельца):** функции «заказать вторую редактуру» у нас НЕТ. Есть **ре-проход**, законный только при СДВИНУВШЕМСЯ банке — человек исправил термин и просит пере-прогнать книгу. ⇒ верное утверждение узкое: **ре-проход пере-делывает затронутую единицу ЦЕЛИКОМ** тем же редакторским промптом (режима «правь только термин» в движке нет), **прежний текст остаётся в чекпойнтах, но без адреса** — ни одна строка статуса на него не указывает, экспорт его не видит, отката нет; **и ничто нигде не сравнивает старый вывод с новым**. ⛔ **Единственный БЕЗВОЗВРАТНЫЙ путь найден:** ре-проход флагнулся → оператор делает `redrive` → сброс стадий сносит чекпойнты **ФЛАГНУТОЙ стадии по всем снапшотам**, и прежний хороший чекпойнт РЕДАКТУРЫ в их числе. ⚠ **Испр. 06.09: стояло «ВСЕ чекпойнты чанка» — шире правды**, черновая строка уцелевает (`backend/internal/pipeline/volume.go:717`=`deletes only the FLAGGED and SKIPPED`). Довод о безвозвратности от этого не страдает: теряется именно принятая редактура. ⚠ Попутно: комментарий `backend/internal/store/chunkstatus.go:52-57` про «резюм переписывает строку» ЛОЖЕН — обычный резюм её не пишет. ⭐ Это ЯДРО гипотезы 1 отчёта `research/32`, и консилиум его ПОДТВЕРДИЛ — единственная его архитектурная часть, устоявшая целиком. ⚠ Полный revision-контур (схема, семантика `chunk_status`, экспорт, контракт, платформа) — смена курса и дизайн-пак масштаба строки 161, НЕ заказ этой строки. **Заказ здесь узкий: указатель принятой редакции**, чтобы повторная попытка не могла уничтожить принятое | бэкенд+платформа | скоро | вторая редактура не может отнять первую | **D39.215** | -| 323 | **ЧЕСТНАЯ ЦЕНА ПРАВКИ БАНКА — НЕ «ПЕРЕПОКУПКА КНИГИ», И ЭТО МЕНЯЕТ ДОВОД, КОТОРЫМ ЗАЩИЩАЛИ БЕЗДЕЙСТВИЕ.** ⛔ **ФОРМУЛА ПЕРЕПИСАНА 06.09 ПО ЗАМЕРУ — прежняя редакция была завышена в ТРЁХ местах.** Верно: подпись через `bank-apply` двигает ТОЛЬКО редакторскую волну и стоит **единицы, чей исходник содержит ключ термина внутри его окна** (плюс те, где термин перестал инжектироваться); остальное ре-пиньтся за $0 **при явном `--resnapshot`**. Правка СИДОВОГО файла двигает обе волны и добавляет черновые чанки с ключом плюс **до двух следующих чанков той же главы** (рябь переноса), а также все единицы с перекупленным черновиком — **последнего смета НЕ ВИДИТ**. ⛔⛔ **И главный денежный член был пропущен: проход терминолога перекупается НА КАЖДУЮ ПОДПИСЬ, он тратится ДАЖЕ БЕЗ `--resnapshot`, и его ПЕРЕПОКУПКА невидима смете и согласию** (⚠ испр. 06.09: стояло «невидим смете» без оговорки — шире правды: смета ПЕРВОГО прогона проход несёт потолком, `backend/internal/pipeline/priceprojection.go:317`=`BookOnceUSD: r.bookOnceUSD()`; невидима именно перепокупка на подписи, строка 38) (центы: $0.005 на четырёх главах, $0.026+$0.034 на десяти; потолок — бюджет). ⚠ Прежнее «опровергнуто кодом и тестом» тоже сильнее правды: пин доказывает игрушечный случай — две главы по чанку, mined-only, без прохода майнинга, без ряби и каскада. ⚠ Значение: «оставить как есть, потому что чинить дорого» — довод, которым закрывали вопрос неверной банковой строки, — **отпадает по цене**. Сам закон банка при этом НЕ оспаривается: доказательств против `D39.104` нет ни у одного голоса. ⚠ Оговорки названы и не спрятаны: бесплатность неполная, проход терминолога пере-покупается (строка 38), и всё это только при ЯВНОМ `--resnapshot` | оркестратор | скоро | цена правки банка названа формулой, а не страшилкой | **D39.215** | -| 324 | **ВХОД РЕНДЕРА ЗАКРЫТ: СОСЕДНЕЕ ПОВЕСТВОВАНИЕ НЕЛЬЗЯ ПОДАТЬ ДАЖЕ ПРАВКОЙ ПРОМПТА.** Шаблон принимает фиксированный набор плейсхолдеров, неизвестный `{{…}}` — жёсткая ошибка. ⇒ на дежурный ревью-вопрос «заработает ли это без правки Go» ответ здесь сегодня **«нет»**, и это признанный долг, а не дефект: пара-данные общности так и задуманы, но ИМЕННО этот вход расширяется только кодом. ⛔ **ИСПР. 06.09: сцепка со строкой 321 была МИМО ПРЕДМЕТА** — там переносятся id банковых строк по инъекционному каналу, а не через шаблон, и в шаблон это не упирается вовсе. В шаблон упирается только «дать редактору соседний ТЕКСТ», и это отдельная гипотеза. ⚠ И это НЕ долг общности: набор — движковые рантайм-значения, пар-специфики в нём нет; таблица в данных стала бы вторым носителем. ⇒ **строить не надо**, предмет переформулирован в контракт входа. Если гипотеза соседнего текста подтвердится замером — правка Go снапшот НЕ двигает, но использование в боевом промпте двигает его через хеш промпта ⇒ редакторская волна перекупается ОДИН раз | бэкенд | когда-нибудь | вход рендера расширяем данными либо отказ объявлен в носителе | **D39.215** | - -| 325 | ⛔ **«МЫ ПРОСТО НЕ БУДЕМ ВПУСКАТЬ EPUB И НЕ-CJK» — СЕГОДНЯ НАМЕРЕНИЕ, А НЕ ФАКТ: ИНТЕЙК ИХ ПРИНИМАЕТ.** Замер 06.09: приём и обработка имени `.epub` закреплены тестом платформы (`platform/internal/books/books_test.go`, кейсы с расширением), то есть сужение входа до того, что умеет ВЫДАЧА, — это **код, а не решение**. ⚠ Значение прямое: строка 283 держит «структура глав для выдачи гейтит бету для не-CJK и EPUB», и её компенсация на бете («просто не впускаем») не работает, пока отказа нет в коде. ⇒ либо интейк отказывает форматам, чью выдачу мы не умеем, с честной причиной пользователю, либо 283 обязана быть сделана ДО впуска. ⭐ Найдено разбором границы беты 06.09; предмет — компенсация, объявленная и не построенная | платформа | скоро | вход физически сужен до того, что умеет выдача, либо выдача умеет впускаемое | **D39.215** | -| 326 | ⛔ **ПОНЯТИЯ «БЛОКЕР БЕТЫ» В ТРЕКЕРЕ НЕТ, И КРИТЕРИЯ ВПУСКА ПЕРВОГО ПОЛЬЗОВАТЕЛЯ В РЕПОЗИТОРИИ НЕ СУЩЕСТВУЕТ.** Замер 06.09: гейт печатает «блокеров очереди: 0», но этот вес — про ОЧЕРЕДЬ, а не про бету; слово «бета» в строках бэклога встречается считаное число раз и НИ РАЗУ не как критерий впуска (⚠ счёт из строки снят 06.09: я привёл «три из 236», а пере-счёт даёт 5 из 229 — оба числа были неверны, а утверждение в них не нуждается); греп по `docs/`, `platform/docs/`, `backend/docs/` на «первый пользователь / первая внешняя книга / впуск» не даёт ничего. ⇒ **вопрос «сколько ещё до беты» не читается из трекера не потому, что мало сделано, а потому что трекер никогда не нёс этого понятия.** ⚠ Практическое следствие: любой ответ о сроке беты сегодня — оценка сессии, а не состояние проекта, и проверить его нечем. ⇒ заказ: **линия остановки как ПРОВЕРЯЕМОЕ условие** (прогон на чужом файле через ту же дверь · деньги сходятся либо маржа видна пользователю · застрявший прогон видно и лечится · ни один экран не врёт о единице · вход сужен до того, что умеет выдача) — формулировку утверждает ВЛАДЕЛЕЦ, носитель заводит оркестратор | владелец → оркестратор | скоро | в дереве есть проверяемый критерий впуска первого внешнего пользователя | **D39.215** | - -| 327 | ⛔ **ОСТАТОК ПОЛИГОН-ПАКЕТА №4 ЖИВЁТ ТРИ МЕСЯЦА ВНУТРИ ПРОМТА, И В НЁМ ЛЕЖИТ ДАТИРОВАННЫЙ РИСК.** ⚠⚠ **Срочное: замерный судья `memory_eval.py` работает на `gemini-2.5-flash`, у серии объявлен shutdown **16.10.2026** — около шести недель от 06.09.** Носителя у этого НЕ БЫЛО: единственное вхождение слага в бэклоге — проза про ЦЕНЫ другой модели, а не про миграцию нашего судьи (проверено грепом по предмету, не по имени). ⇒ после отключения замерный контур встанет, и узнаем мы это отказом, а не планом. Там же: двойной `extra_body` и отсутствие 404-ретрая при живом слаге. ⚠ Остальные пять пунктов остатка, тоже без носителей: матчер content-filter подстрокой + самотест · параметризация языка/жанра судейского промпта (ja/en сняты под zh-рамкой) · проба судьи-дублёра 18+ · калибровка echo-gate (`D25.7`) · minimal-pairs 100–150 для shadow fidelity (`D25.2`). ⭐ **Класс, а не случай:** промт `POLYGON_PACKAGE4_SESSION_PROMPT.md` с 12.07 стоит «частично отработан, residual ЖИВ», как отдельная сессия НЕ запускался — то есть **носителем работы служит промт, а не трекер**, и в трекере этой работы не видно вовсе. ⇒ заказ: остаток становится строками, промт уходит в архив с баннером исхода, а в ролевой промт оркестратора вносится правило выхода «residual → строка бэклога, промт в архив» — сегодня его там нет, и именно поэтому пакет №4 жив три месяца | полигон | скоро (миграция судьи — ДО 16.10) | остаток несут строки, промт в архиве, правило выхода записано | **D39.216** | +> ⟶ **ПЕРЕЕХАЛ 06.09 в [BACKLOG.md](BACKLOG.md)** (ратификация — D39.218). Таблица вынесена дословно, **номера строк не менялись**: «строка N» ищется там же, чем и здесь — `grep -n '^| N |' docs/BACKLOG.md`. Заголовок оставлен НАМЕРЕННО, чтобы прежние ссылки «секция „Бэклог“ в PROGRESS» доезжали в один хоп. Счёт очереди — бюллетенем в шапке того файла; **здесь копии НЕТ** (один носитель на факт, D39.112). *(Указатели на архив-слайсы хроники — бюллетенем «Архивы хроники» в CURRENT-STATE; здесь копий нет.)* diff --git a/docs/README.md b/docs/README.md index 1f14a7c8..d08c990f 100644 --- a/docs/README.md +++ b/docs/README.md @@ -2,7 +2,7 @@ Проект: издательский художественный перевод крупных текстов (книги, ранобэ, вебновеллы) мультиагентным пайплайном поверх LLM API; **пара языков — данные, не код**, сегодня боевая zh→ru. Go-бэкенд + веб-фронт ридер-IDE (Ф3) + платформа (SaaS control plane, `platform/`, D39.81). Цели и мерило — канон в [../CLAUDE.md](../CLAUDE.md); онбординг сессий — там же. Стартовый бриф владельца: [../START_PROMT.MD](../START_PROMT.MD) — **живой документ**, его V-идеи разобраны в реестр требований (ниже). -**Состояние проекта НЕ здесь** — кроме таблицы активных промтов ниже, и это осознанное исключение: она отвечает на вопрос «какой файл мой», без которого холодная сессия выбирает роль сама (проверено слепым замером входа). Всё остальное состояние — Очередь, курс, бэклог — CURRENT-STATE в шапке [PROGRESS.md](PROGRESS.md); решения — [architecture/05-decisions-log.md](architecture/05-decisions-log.md) (при конфликте с любым доком побеждает он). Эта страница — только карта «что где лежит». +**Состояние проекта НЕ здесь** — кроме таблицы активных промтов ниже, и это осознанное исключение: она отвечает на вопрос «какой файл мой», без которого холодная сессия выбирает роль сама (проверено слепым замером входа). Всё остальное состояние — Очередь и курс — CURRENT-STATE в шапке [PROGRESS.md](PROGRESS.md), а долг — единый бэклог [BACKLOG.md](BACKLOG.md); решения — [architecture/05-decisions-log.md](architecture/05-decisions-log.md) (при конфликте с любым доком побеждает он). Эта страница — только карта «что где лежит». ## Карта @@ -15,7 +15,8 @@ - Исторические, читать через ⚠-баннеры: [01-decisions.md](architecture/01-decisions.md) (Р1–Р10) · [02-mvp-plan.md](architecture/02-mvp-plan.md) · [03-implementation-notes.md](architecture/03-implementation-notes.md) · [04-unhappy-paths.md](architecture/04-unhappy-paths.md) · [06-memory-risk-registry.md](architecture/06-memory-risk-registry.md). - `experiments/` — эмпирика полигона: [00-provider-quirks.md](experiments/00-provider-quirks.md) — **читать перед любым вызовом провайдера**; [08-cost-model-v2.md](experiments/08-cost-model-v2.md) — денежная модель; [09-pilot-protocol.md](experiments/09-pilot-protocol.md) — пилот Ф2.5; остальные — отчёты экспериментов. ⚠ **У каждого отчёта статус в его ревью-шапке: читай шапку прежде тела** — она первична и говорит, ратифицированы выводы или заморожены. - `research/` — фактура ресёрчей; у принятых — ревью-шапки, часть тел под ⚠ superseded: **читай баннер прежде содержимого**. Ключевые для навигации: 15 голос · 16 ридер-IDE · 17 внешняя критика · 18 рычаги качества · 19 нарезка · 20 банк-майнинг · 21 обзор транспорта · 22 доменные харнессы · 23 шов движок↔платформа · 25 холодное ревью шва — **читать перед любым кодом стыка** · 24 арбитраж банка · 26 официальные практики Anthropic · 28 контракт-ревью API v0 — **носитель для исполняющих сессий, читать оригинал, не пересказ**. -- [PROGRESS.md](PROGRESS.md) — журнал: CURRENT-STATE + **ЕДИНЫЙ БЭКЛОГ** (единственный трекер) + живой хвост хроники. НЕ источник решений. +- [PROGRESS.md](PROGRESS.md) — журнал: CURRENT-STATE + состояние паков + живой хвост хроники и зонные секции «Бэкенд»/«Полигон». НЕ источник решений. +- [BACKLOG.md](BACKLOG.md) — **ЕДИНЫЙ БЭКЛОГ проекта** (единственный трекер; «строка N» — стабильный ID). Вынесен из `PROGRESS.md` 06.09 (D39.218; исключение из дословности названо в шапке того файла); зонные бэклоги — свои и с другими ID (`П-N`, `Ф-N`, `PD-N`). - **Тулчейн на чистой машине.** Версии не здесь — их носители: `backend/Makefile` и `platform/Makefile` (`GO_MIN_VERSION`, `GOLANGCI_VERSION`), `frontend/package.json` (`engines`), `platform/docs/STACK_DECISIONS.md` §«Postgres на стенде без root», `eval/requirements.txt` + `eval/.python-version`. Здесь только то, чего нет нигде: ставим в `~/.local/opt/<инструмент>` с симлинком в `~/.local/bin` (он уже в `PATH`), берём **последний патч пинованного минора, а не следующий минор** — линтер пинован точным равенством и разъедется. Root требуют ровно два пакета: `build-essential` (без C-компилятора нет `-race`, а снять `-race` значит выдать отсутствие тулчейна за зелёный прогон — см. комментарий над целью `test` в `backend/Makefile`) и `python3-venv` (в системном питоне нет `ensurepip`, и установка полигона по `eval/README.md` обрывается на первом шаге). - `scripts/counts.py` — **производные числа доков считаются им, а не руками** (голова по трём носителям · счёт очереди и зон · вес открытых строк регистра платформы · полнота реестра нот); `--check` даёт ненулевой код на расхождении; `--lint` — линтер file:line-якорей живых доков (D39.126). Его же зовёт зонный хук `scripts/githooks/pre-commit`: **`--lint` якорей — при ЛЮБОМ коммите с непустым индексом, включая коммиты чистого КОДА (гейт по составу снят 21.08: цели якорей живут в коде, и двигает их кодовый коммит; шумовое следствие — строка бэклога 244); `--check` чисел и головы — только при коммите с D-логом или PROGRESS** (оба `--from-index`, предупреждает, не блокирует). ⚠ **Гейт бутстрапится ЧУЖОЙ зоной — это ДЕФЕКТ, а не порядок работы (строка бэклога 220):** судит он `CLAUDE.md` и доки трёх зон, а в `.git/hooks/` его кладёт единственный установщик `frontend/scripts/githooks/install.mjs`, то есть побочный эффект `npm install` в зоне, которая ЗАМОРОЖЕНА. На свежем клоне `.git/hooks/` пуст и гейт молчит, не проверив ничего. Пока строка открыта, бутстрап делается руками (`node frontend/scripts/githooks/install.mjs`) — и это ВРЕМЕННАЯ мера, которую строка 220 закрывает, а не способ жить дальше. ⚠ Шапка систематически отстаёт от хвоста у ЛЮБОГО автора — потому проверка механическая, а не «посмотрю внимательно». - **Активные хендофф-промты — какой файл ТВОЙ** (состав обновляется при каждом лендинге, D39.80; хроника, причины и статусы РАБОТ — CURRENT-STATE и D-лог): diff --git a/docs/STACK.md b/docs/STACK.md index 4c494d3b..07dc3a2f 100644 --- a/docs/STACK.md +++ b/docs/STACK.md @@ -29,5 +29,5 @@ ⚠ И перекос слоя, вскрытый включением: корпус контраста — факт ИСХОДНОГО языка, а лежит в пар-агностичном конфиге пайплайна. Пара, которой в репо нет, потребует своего корпуса и своего ключа. - **Вахта эффорта pro:** реестр загейченных триггеров — `architecture/13-tech-debt-anchors.md` §Б-108 (статус ручки — в строке редактора выше). -- **Цена:** ~$0.85/ранобэ (D30.4; тело — `archive/architecture/05-decisions-D1-D38.md`, карта — шапка D-лога) — ⚠ число ДО пере-пина цен 13–15.08: таблица запинена ПИКОМ, счёт шиппинга = 100% DeepSeek ⇒ ×4.2–4.4 в пике и ×2.1–2.2 в долине (D39.137). ⚠ **Пере-калибровки НЕТ:** первый платный прогон редакторской волной отработал 31.08 (D39.184; числа — `archive/reports/COLDRUN_V16_REPORT_2026-08-31.md`), пересчёта книги из него никто не сделал — фактура и статус довода «редактор не гонялся» в `PROGRESS.md` строка 16. Ставка платформы $0.03/глава (D39.123 п.2г). Цены слагов — `models.yaml` (**`2026-08-15`**: `backend/configs/models.yaml:34`=`prices_checked: "2026-08-15"`; ⚠ бампнут факт-чеком ТОЛЬКО по DeepSeek; катовер 0731 цен не менял). +- **Цена:** ~$0.85/ранобэ (D30.4; тело — `archive/architecture/05-decisions-D1-D38.md`, карта — шапка D-лога) — ⚠ число ДО пере-пина цен 13–15.08: таблица запинена ПИКОМ, счёт шиппинга = 100% DeepSeek ⇒ ×4.2–4.4 в пике и ×2.1–2.2 в долине (D39.137). ⚠ **Пере-калибровки НЕТ:** первый платный прогон редакторской волной отработал 31.08 (D39.184; числа — `archive/reports/COLDRUN_V16_REPORT_2026-08-31.md`), пересчёта книги из него никто не сделал — фактура и статус довода «редактор не гонялся» в `BACKLOG.md` строка 16. Ставка платформы $0.03/глава (D39.123 п.2г). Цены слагов — `models.yaml` (**`2026-08-15`**: `backend/configs/models.yaml:34`=`prices_checked: "2026-08-15"`; ⚠ бампнут факт-чеком ТОЛЬКО по DeepSeek; катовер 0731 цен не менял). - **Ключи API:** какой ключ нужен провайдеру — поле `api_key_env` в `models.yaml`, один носитель на факт. **`.env` НЕ читать** (гардрейл CLAUDE.md), `.env.example` можно. Ключи деплоя доезжают до движка аргументом `--keys-file` (движковая половина — D39.158, платформенная — пак P9); в окружение юнита ключи НЕ кладутся, и каталог пользовательского контента их больше не несёт. Строка бэклога **211** ЗАКРЫТА — история дефекта и его разбор в D39.156/D39.162. diff --git a/docs/architecture/01-decisions.md b/docs/architecture/01-decisions.md index 0121068e..c66155d2 100644 --- a/docs/architecture/01-decisions.md +++ b/docs/architecture/01-decisions.md @@ -64,7 +64,7 @@ Контент-роутинг ([11-gap-2](../research/11-gap-2.md)): - Механизм роутинга **переопределён D39.25**: не чанк-классификатор «горячести» 0–3, а content-label книги/главы × `accepts_labels` провайдера (`backend/configs/models.yaml`, подписи D39.30); L3 — политика ВХОДА. Живые инварианты этой строки: жёсткий отказ только на CSAM-категории (Р8) и «ложное срабатывание не убивает многочасовую оплаченную джобу» — чанк помечается в отчёте, глава и книга продолжают обрабатываться. - **Эскалация channel-aware**: для чанков канала B дорогая эскалация — Grok 4.3 / Gemini (safety off) / крупные open-weights; канал A — DeepSeek V4 Pro / GLM-5.1 / Gemini 3.1 Pro; OpenAI **в канал B не включать** (политика 18+ строгая, adult mode заморожен). Инвариант «непермиссивная нога не получает помеченный контент» живёт как fail-closed `accepts_labels` (D39.26/D39.28; `failover.go` удалён). -- Гигиена аккаунтов xAI **снята D27**: ключ единый, с data-sharing на тесты/пилот; живой остаток — отключить data-sharing перед продом (строка 67 бэклога `../PROGRESS.md`). Провайдер лёг → роль пауза→resume (D4, не сайлент-своп). Think-ON на Grok — только после reasoning-буфера в EstimateUSD (D6.2); off-switch и аддитивность reasoning — `experiments/00-provider-quirks.md`. +- Гигиена аккаунтов xAI **снята D27**: ключ единый, с data-sharing на тесты/пилот; живой остаток — отключить data-sharing перед продом (строка 67 бэклога `../BACKLOG.md`). Провайдер лёг → роль пауза→resume (D4, не сайлент-своп). Think-ON на Grok — только после reasoning-буфера в EstimateUSD (D6.2); off-switch и аддитивность reasoning — `experiments/00-provider-quirks.md`. - Обязателен **детектор молчаливых вырезаний** (сверка покрытия предложений вход↔выход) — Qwen-подобные внешние фильтры молча портят перевод. - Внутренний refusal/excision-бенчмарк (50–100 фрагментов), прогонять при каждой смене версии модели. - Для политически чувствительных zh-текстов — не полагаться на китайские API (цензура в весах), фолбэк на западные/локальные. diff --git a/docs/architecture/03-implementation-notes.md b/docs/architecture/03-implementation-notes.md index 12eda84c..8e995ce7 100644 --- a/docs/architecture/03-implementation-notes.md +++ b/docs/architecture/03-implementation-notes.md @@ -109,7 +109,7 @@ C2, cache TTL per-стадия. В models.yaml: цены (+cache write/read), п Селфревью Фазы 0 (скелет `7954325` → волна 1 `e861541` → волна 2 `214e005`) и независимое внешнее ревью **приняты, блокеров ноль**; хроника волн и диспозиция находок F1–F8/D1–D3 — `../archive/PROGRESS-2026-07-04-10.md` (§«Фаза 0 принята»). Из тогдашнего техдолга ЗАКРЫТО: гонка `Runner.clients` (клиенты строятся eager-проходом ДО волн, дальше map read-only — `internal/pipeline/runner.go`, греп `the clients map is READ-ONLY in the waves`; D39.13) · F4 «finish=length с обрезанным черновиком» (флаг диспозиции `FlagLength` — `internal/pipeline/disposition.go`, греп `FlagLength FlagReason`) · F3-класс оплаченных ретраев (кап пере-биллинга: второй нечитаемый оплаченный 2xx ТЕРМИНАЛЕН, ре-биллы капятся одним — `internal/llm/httpllm.go`, греп `Cap billed-decode re-bills at ONE`) · D1/D2 (билингв-редактор ратифицирован D30.1 — требование «убрать `{{text}}`» ОТМЕНЕНО, не исполнять; per-chunk skip+flag построен диспозиция-классификатором) · D3 (изоляция канала B: `failover.go` удалён, механизм лейблов `content_labels`×`accepts_labels` — D39.26/27/28). -**Живой остаток (носители — бэклог-строка 146 `docs/PROGRESS.md`, греп `Два техдолга движка без строки трекера`):** +**Живой остаток (носители — бэклог-строка 146 `docs/BACKLOG.md`, греп `Два техдолга движка без строки трекера`):** - **Дневной потолок — пер-книжный** (ledger в файле проекта одной книги): `day_usd` сбрасывается в UTC-полночь и ограничивает burn-rate одной книги, а не «оператора за день по всем проектам»; общий потолок потребует shared spend-файла (раскладка «файл БД на книгу» из Р3/Р6). Платформенная половина — `PD-157`. - **`prices_checked` (120 д) гейтит read-only `report` и $0-resume** (F6): платных вызовов они не делают, но падают на устаревших ценах. ⚠ Приёмка D39.134: этот же гейт работает ДЕТЕКТОРОМ самолечения деплоя — снимать его бездумно нельзя. - **`cache_ttl` ↔ `cache_write_per_m`**: цена записи в кэш в models.yaml задана под ОДИН TTL (боевой 5m). При `cache_ttl: 1h` реальная запись стоит ×2, а не ×1.25 — недоучёт; вторая цена/валидация нужны при осознанном переходе на 1h. diff --git a/docs/architecture/05-decisions-index.md b/docs/architecture/05-decisions-index.md index 4ea31705..52607230 100644 --- a/docs/architecture/05-decisions-index.md +++ b/docs/architecture/05-decisions-index.md @@ -1,4 +1,4 @@ -# Реестр D-нот — карта актуальности v2 (D1–D39.217; титул — носитель головы, бампать при каждом аппенде) +# Реестр D-нот — карта актуальности v2 (D1–D39.218; титул — носитель головы, бампать при каждом аппенде) > ⚠ **Колонку «тело» `counts.py --check` НЕ сторожит по устройству:** он сверяет полноту НОМЕРОВ, а не > место тела, поэтому колонка держится дисциплиной лендинга. Не нашёл тело по колонке — иди в слайсы, @@ -7,7 +7,7 @@ > Одна строка на КАЖДУЮ ноту журнала решений: № · дата · суть · статус · где тело · темы. > ⚠ **ФОРМА ДВУХ ПОСЛЕДНИХ КОЛОНОК РАЗЪЕХАЛАСЬ, замерено 30.08 (аудит доков):** из 224 строк 74 несут в колонке «статус» не статус, а ЗАМЕТКУ о живом остатке («ЖИВОЕ: …»), а собственно `жив` уехал в колонку «тело». Читать так: **колонки 4–5 у свежих нот — пара «статус ⟷ что осталось живым», порядок в паре не гарантирован; статус ноты определяй по слову `жив`/`superseded`/`частично`, где бы из двух оно ни стояло, а место тела — по слову `слайс`.** Приведение к одной форме — строка бэклога **242**; чинить руками 74 строки без гейта дороже, чем читать по этому правилу. Ведёт оркестратор при лендингах: новая нота = новая строка ТЕМ ЖЕ коммитом (полноту сторожит `docs/scripts/counts.py --check`). Суть и статус здесь — НАВИГАЦИЯ, не контракт: при конфликте побеждает ТЕЛО ноты (живой [`05-decisions-log.md`](05-decisions-log.md) → слайсы `../archive/architecture/05-decisions-*.md`). Несущие эрраты к фактам старых нот живут в шапке живого D-лога — их читать ОБЯЗАТЕЛЬНО, реестр их не дублирует. Темы (для грепа оси «какой закон по X»): деньги · шов · банк · промпт · судья · гейты · контракт · платформа · фронт · полигон · ToS · общность · процесс · нарезка · голос · инфра · модели. > Легенда колонки «тело»: «жив» = живой D-лог, «слайс N» = `../archive/architecture/05-decisions-N.md` (родословная реестра — D39.126 п.1(а)). -> ⚠ **«ЖИВОЕ: строка N» — снимок НА МОМЕНТ ноты.** ID закрытой строки бэклога `../PROGRESS.md` ИСЧЕЗАЕТ (закрытая уходит в D-лог с номером решения, ID не переиспользуется), поэтому «строки N в трекере нет» читается как ЗАКРЫТА, а не как битая ссылка — замерено 02.09: так уехали ссылки 18 строк реестра. +> ⚠ **«ЖИВОЕ: строка N» — снимок НА МОМЕНТ ноты.** ID закрытой строки бэклога `../BACKLOG.md` ИСЧЕЗАЕТ (закрытая уходит в D-лог с номером решения, ID не переиспользуется), поэтому «строки N в трекере нет» читается как ЗАКРЫТА, а не как битая ссылка — замерено 02.09: так уехали ссылки 18 строк реестра. | № | дата | суть | статус | тело | темы | |---|---|---|---|---|---| @@ -276,3 +276,4 @@ | D39.215 | 06.09 | **ОТЧЁТЫ КОДЕКСА: ПОЛЕЗНЫ, НО РАТИФИЦИРУЮТСЯ ПРОВЕРЕННЫЕ УТВЕРЖДЕНИЯ, А НЕ ФОРМУЛИРОВКИ** (консилиум: 40 клеймов, 31 подтверждён, 3 опровергнуты). ⛔ Центральное обвинение п.2 ОПРОВЕРГНУТО — принять его значило снять не то основание. ⭐ Сильнейший довод в отчётах ОТСУТСТВУЕТ: прибор замера штрафует поведение, которое сам заказывает. ⛔ Постчек банка молчит ровно тогда, когда сбывается названный им страх владельца. Строки 318–320 | ✅ | | D39.216 | 06.09 | **МАНДАТ ЧИСТОТЫ (решение владельца)**: проектировать и рефакторить без хаков и воркэраундов, где форма не тянет — переписывать; «дешевле подпереть» доводом не является; отступление объявляется С ЦЕНОЙ. ⛔ Носителя не было ВОВСЕ (ноль вхождений); `CLAUDE.md` нёс более узкое — запрет обходить НАЙДЕННУЮ ошибку. Обязан стоять строкой в каждом паке с проектированием | ✅ | | D39.217 | 06.09 | **ПЕРЕДАЧА №22 → №23**: четыре потока в шапке PROGRESS · три нормы смены (дерево+популяция и ДРУГОЙ прибор · контрольная величина ПЕЧАТАЕТСЯ · мутация по ТЕКСТУ) · класс «прибор ответил на свой вопрос» — 8+ раз у всех ролей · **чем врал оркестратор** (комментарии вместо тестов, числа из писем, суд по заголовку) · датированный риск 16.10 · вопросы владельца | ✅ | +| D39.218 | 06.09 | **ЕДИНЫЙ БЭКЛОГ ВЫНЕСЕН В `docs/BACKLOG.md`** (решение владельца): таблица и бюллетень счёта перенесены побайтно, ID строк прежние, на месте — заголовок-указатель; `counts.py` и зонный хук переведены тем же коммитом. Замер формы: из 250 коммитов PROGRESS с 25.08 «только бэклог» 48 из 148 ⇒ ловушка «уношу чужое» снимается на 32 %, с бюллетенем 58 %; остаток — зонные секции, строка **328** | жив | ЖИВОЕ: строка 328 (зонные журналы бэкенда и полигона — на владельце); мутация «снять заголовок» гейтом НЕ ловится — п.5 | доки трекер гейт процесс | diff --git a/docs/architecture/05-decisions-log.md b/docs/architecture/05-decisions-log.md index 890f1032..15507741 100644 --- a/docs/architecture/05-decisions-log.md +++ b/docs/architecture/05-decisions-log.md @@ -1,4 +1,4 @@ -# Журнал решений оркестратора — контракт D1–D39.217 (живой файл: карта · эрраты · живые тела · голова D39.124+ (подрезка D39.139); тела закрытых эр — в слайсах `docs/archive/architecture/`, указатель ниже; реестр всех нот — `05-decisions-index.md`) +# Журнал решений оркестратора — контракт D1–D39.218 (живой файл: карта · эрраты · живые тела · голова D39.124+ (подрезка D39.139); тела закрытых эр — в слайсах `docs/archive/architecture/`, указатель ниже; реестр всех нот — `05-decisions-index.md`) > **⟶ КАРТА АКТУАЛЬНОСТИ (ревизия D31, продлена до D38.2 [12.07]; исторические записи ниже НЕ переписываются — дисциплина D23.3).** Работая с контрактом (греп номера: живой файл → слайсы, целиком НЕ читать — D39.125), держи под рукой, что чем перекрыто: > ⚠ **Эррата 09.08 (D39.125):** D39.111 п.1 предписывал промту S3 «максимум = баланс МИНУС открытые холды» — формула ОШИБОЧНА (вычитание дважды), исправлена D39.115 п.2(а): максимум = Balance КАК ЕСТЬ; тело D39.111 — в слайсе `../archive/architecture/05-decisions-D39-106-123.md` (испр. 05.09: прежнее «живёт ниже в этом файле» протухло подрезкой D39.139) (голова D39.106+). @@ -18,7 +18,7 @@ > ⚠ **Эррата 27.08-е (D39.159 п.8, финал): `PD-398` ЗАКРЫТА — у построенного гейта появился пин.** `selftest_tail_vocab()` гоняется на каждом `--check`, четыре утверждения, проверен ПОСАДКОЙ трёх мутаций самого гейта (все три пойманы, базовая линия молчит). ⚠ Первая редакция пина молчала на одной из трёх: утверждение про вес проверяло `cells()`, а мутация меняет то, чем пользуется `register()`. Пин, проверенный одним прогоном вместо посадки, — ровно тот класс, который эта строка описывает; поймано только потому, что посадку сделал. Регистр 96 → 95 открытых. > ⚠ **Эррата 27.08-ж (D39.160 п.2) — ошибка ОРКЕСТРАТОРА, найденная исполнителем пака.** Нота утверждала, что после сноса отменённой двери «канон и деплой СОВПАДУТ точно», а промт минора (§3.2-бис) — что счётчики `pending_decisions`/`complete` «навсегда нули». **Верно по ПУТЯМ, неверно по ПОЛЯМ:** проекция `GET /bank` продолжает их слать, и это не нули — `bankCountsTx` (`platform/internal/pgstore/readmodel.go:330`) считает `proposed`-строки, о чём говорит её собственный комментарий. Клиент 0.5.0 лишние поля игнорирует, но аллоулист-норма нарушена до монтажа (2в). Носитель — `PD-399`. ⚠ Контрактная сессия принесла это ПИНГОМ по §11 промта, вместо того чтобы тихо подогнать работу под неверную посылку; это и есть поведение, которого норма требует. > ⚠ **Эррата 27.08-з (D39.156, состав пункта 2в): «воркер решений → глагол перед возобновлением» СНЯТ — посылка изменилась.** Пункт писался, когда двери в контракте не было и подразумевалось НАКОПЛЕНИЕ: платформа копит решения у себя и скармливает их движку перед `resume`. С дверью канона 0.5.0 накопления не существует — правка ПРИМЕНЯЕТСЯ в момент подачи, и гарантия «до возобновления» у синхронной формы СИЛЬНЕЕ воркерной: применено прежде, чем клиент получил `200`. Проверено исполнением с обеих сторон: движок на стопе ВЫХОДИТ (`cmd/tmctl/main.go:95`, код 3), флок не-блокирующий и отпускается ядром на выходе процесса (`store/store.go:187`), между стопом и возобновлением живого процесса на проекте нет — запинено `pipeline/bankchain_test.go:62-64`; кап 5000 решений выведен ИМЕННО из синхронности («the call stops fitting the caller's timeout»). Остаётся не воркер, а пер-книжная сериализация в обработчике. `Resume` «с решениями как они есть» не тронут. -> ⚠ **Эррата 28.08-и (D39.165 §3, размер мины) — ошибка ОРКЕСТРАТОРА, найденная опровергателем промта P10.** Нота утверждает: «первый же ПРОДОЛЖАЮЩИЙ прогон после первой же правки банка УПАДЁТ». **Переоценено.** Гард снапшота стреляет по СУЩЕСТВУЮЩЕМУ джобу (`backend/internal/pipeline/stagerun.go:47`=`r.Store.EnsureJob` — `EnsureJob` создаёт джоб стадии в момент, когда стадия впервые исполняется), а правка в ГЛАВНОМ окне — стоп подписи `awaiting_bank` — двигает edit-снапшот, когда edit-джобов ЕЩЁ НЕТ: возобновление создаёт их свежими, и гард молчит. Драфт-волна mined-строк не видит вовсе (`backend/internal/pipeline/bankmaterialize.go:317`=`if row.Source == "mined"` (⚠ адрес испр. 06.09; ФОРМУЛИРОВКА испр. по эррате 06.09-ж: переименования НЕ было — `seeding.go` жив, а код ВЫДЕЛЕН в `bankmaterialize.go` (`6ec9f8a` 29.08). Линт не мог угадать адрес по другой и более простой причине: прежний якорь был написан ГОЛЫМ именем, а такое имя отсеивается на `docs/scripts/counts.py:592`=`"~" in rel or "/" not in rel` ДО всякой проверки файла — нашёл `git log -S` по тексту якоря)). **Дефект СТОИТ, но его триггер уже: правка, сделанная ПОСЛЕ появления edit-джобов** — пауза потолком посреди редактуры и ДОЧИТАННАЯ книга. ⚠ Срочность при этом НЕ падает: флагманский случай продукта («поправил имя героя в дочитанной книге») — ровно тот, где edit-джобы существуют, то есть мина бьёт именно по нему. **Цена ошибки была бы прямой:** репро на потоке `awaiting_bank` показало бы ЗЕЛЕНЬ без фикса, и пак мог быть отозван как мнимый. Промт P10 §4.2 исправлен: репро обязано фиксировать состояние «edit-джоб существует ДО правки». +> ⚠ **Эррата 28.08-и (D39.165 §3, размер мины) — ошибка ОРКЕСТРАТОРА, найденная опровергателем промта P10.** Нота утверждает: «первый же ПРОДОЛЖАЮЩИЙ прогон после первой же правки банка УПАДЁТ». **Переоценено.** Гард снапшота стреляет по СУЩЕСТВУЮЩЕМУ джобу (`backend/internal/pipeline/stagerun.go:47`=`r.Store.EnsureJob` — `EnsureJob` создаёт джоб стадии в момент, когда стадия впервые исполняется), а правка в ГЛАВНОМ окне — стоп подписи `awaiting_bank` — двигает edit-снапшот, когда edit-джобов ЕЩЁ НЕТ: возобновление создаёт их свежими, и гард молчит. Драфт-волна mined-строк не видит вовсе (`backend/internal/pipeline/bankmaterialize.go:317`=`if row.Source == "mined"` (⚠ адрес испр. 06.09; ФОРМУЛИРОВКА испр. по эррате 06.09-ж: переименования НЕ было — `seeding.go` жив, а код ВЫДЕЛЕН в `bankmaterialize.go` (`6ec9f8a` 29.08). Линт не мог угадать адрес по другой и более простой причине: прежний якорь был написан ГОЛЫМ именем, а такое имя отсеивается на `docs/scripts/counts.py:595`=`"~" in rel or "/" not in rel` ДО всякой проверки файла — нашёл `git log -S` по тексту якоря)). **Дефект СТОИТ, но его триггер уже: правка, сделанная ПОСЛЕ появления edit-джобов** — пауза потолком посреди редактуры и ДОЧИТАННАЯ книга. ⚠ Срочность при этом НЕ падает: флагманский случай продукта («поправил имя героя в дочитанной книге») — ровно тот, где edit-джобы существуют, то есть мина бьёт именно по нему. **Цена ошибки была бы прямой:** репро на потоке `awaiting_bank` показало бы ЗЕЛЕНЬ без фикса, и пак мог быть отозван как мнимый. Промт P10 §4.2 исправлен: репро обязано фиксировать состояние «edit-джоб существует ДО правки». > ⚠ **Эррата 28.08-к (D39.165 §3 + решение оркестратора о глава-полосе) — ДВЕ ошибки, обе найдены широким самопроходом платформенной сессии, обе доказаны исполнением.** **(1) Посылка «смета УЖЕ публикуется в `status --json`» верна только ПОСЛЕ свёртки.** `bank-apply` пишет только ФАЙЛЫ решений, а `status` считает ре-билл от СОХРАНЁННОГО глоссария (`backend/internal/pipeline/status.go:962`=`seed-FILE edit` ⚠ (адрес испр. 06.09: цитата УЕХАЛА, не исчезла; в теле `D39.165` она осталась по прежнему адресу — тело ноты не переписывается, D23.3)``, `projectStoredMemory` — его собственный комментарий: «A seed-FILE edit not yet re-run is NOT reflected here… that drift surfaces on the next translate's re-seed»). Свёртка происходит внутри СЛЕДУЮЩЕГО `translate`, поэтому сразу после правки движок отвечает `units=0`/`drift=false`. Следствие: продажа «затронуто N юнитов» и холд от сметы В ТЕКУЩЕМ ШВЕ НЕДОСТИЖИМЫ — для них нужен движковый глагол «свернуть банк и оценить ВНЕ translate», которого нет. **(2) Решение оркестратора «полоса пере-прохода — в ГЛАВАХ» ОТМЕНЯЕТСЯ: его посылка опровергнута.** Я рассудил, что $0-репин двигает полосу, потому что идёт через тот же `resumeFromChunkStatus`, — и не проверил анонс. Движок анонсирует юнит ОДИН РАЗ на жизнь книги (announce-once, `backend/internal/pipeline/events.go:49,143-162`=`announce-once keys`), пере-проход не ре-анонсирует ни репины, ни пере-переводы ⇒ `done` остался бы НУЛЁМ навсегда. Это ровно тот класс, от которого предостерегает памятка «не выводить из соседнего механизма, не проверив свой». ⚠ **Что при этом НЕ отменяется:** запрет класть ЮНИТЫ в поле, объявленное в главах, стоит — но объявленная в каноне «одна единица работы» запретом не является, потому что она НЕ молчаливая. > ⚠ **Эррата 29.08-а (D39.172, две строки, объявленные заведёнными) — ошибка ОРКЕСТРАТОРА №19.** Тело ноты дважды утверждает «Заведено строкой» / «строка заведена» — про `Touch`, выбрасывающий `RowsAffected`, и про пересборку `tmctl` в рецепте стенда. **На момент ратификации ни одной из этих строк не существовало:** последняя строка регистра платформы была `PD-430`, и проверка грепом по `Touch|RowsAffected|пересбор` давала только совпадения слов в чужих строках. Утверждение о будущем записано как о свершившемся — ровно тот класс, который эта же смена ловила у сессий трижды. **СНЯТА 29.08: строки заведены зоной — `PD-431` (`Touch`) и `PD-432` (пересборка `tmctl`), `PD-423` получил вторую точку. Проверено грепом по регистру.** Тело ноты не переписывается (D23.3). ⚠ Сюда же третий пункт того же абзаца: `PD-423` предписано ПЕРЕ-ПРОВЕРИТЬ (у сессии `sqlc` тест зелёный в трёх прогонах), и пометки в строке регистра тоже нет. > ⚠ **Эррата 30.08-б (D39.165 §2 и §3, две находки платформенной сессии P12).** (а) **Якорь протух:** §2 цитирует фразу канона о `chapters_done` по `openapi.yaml:1542-1545` — текст уехал на **`1554-1559`**, по прежним строкам сейчас `RejectReason`. Сама цитата верна дословно; нота не битая, битым стал только номер (класс строки бэклога 219). (б) **§3 назвал живое САМОПРОТИВОРЕЧИЕ канона и не дал ему носителя:** правка банка «takes effect on the NEXT run» (`openapi.yaml:504`) против «finished work is not bought twice» плюс подъём потолка только у ПРИОСТАНОВЛЕННОЙ книги (`:590`) — у дочитанной книги следующего прогона купить нечем, поэтому принятая правка умирает молча. Ни в едином бэклоге, ни в регистре платформы строки не было (проверено грепом по обеим фразам) — **заведена строка бэклога 241** 30.08. ⚠ Класс — «названо в теле ноты и не получило карриера»; норма приёмки требует строку ТЕМ ЖЕ лендингом, здесь она не легла два дня. @@ -42,7 +42,7 @@ > ⚠⚠ **Эррата 06.09-к (`D39.215` п.7) — «ПРЯМОЙ СИЛЬНЫЙ ПЕРЕВОД КАК СОПЕРНИК НЕ ИЗМЕРЕН НИ РАЗУ» НЕВЕРНО, И ЭТО ПЯТАЯ ЗА СМЕНУ ЗАПИСЬ ПО ПАМЯТИ — теперь в ТЕЛЕ ноты, а не в эррате.** Нашёл Fable 5 сверкой с деревом; пере-проверено мной. **Бейк-офф БЫЛ:** `docs/experiments/20-editor-role.md` (принят `D39.108`) нёс армы `direct` («переводит исходник с нуля, черновика нет», боевой промпт переводчика) и `direct-reflow`, судился двумя моделями с зеркальной раскладкой. **Итог: вывод «редактура бьёт прямой перевод 18:6» ОТОЗВАН** — у независимого судьи различие не устояло; разброс судьи на повторе 33 % ⇒ «разница меньше разброса — не сигнал». ⇒ **честная формула: измерен ОДИН РАЗ НА ФРАГМЕНТАХ, различие прибором НЕ РАЗРЕШЕНО, на уровне КНИГИ не мерился.** ⛔ И это ХУЖЕ, чем «не проверял»: проверили, различия не увидели, вывод отозвали — и строили дальше, не повторив. ⚠ Довод п.7 «дорог единственной валютой, которую нельзя купить, — временем владельца» тоже ослаблен: `exp-20` судился МОДЕЛЯМИ, владелец не понадобился. ⭐ **И настоящий соперник назван точнее:** фрагментный бейк-офф ставку проекта проверить не может — ставка живёт на уровне КНИГИ (консистентность терминов, цена, детерминизм), а прямой перевод без банка приоритет №1 не даёт по построению. Честный соперник — **«банк из оригинала + сильный прямой»**, и вот ОН действительно не измерен ни разу (`docs/research/32-harness-architecture-alternatives.md` называет его незакрытым). ⚠ Урок повторный и оттого дорогой: **я написал «ни разу» о предмете, по которому в проекте есть принятый эксперимент с собственной D-нотой** — ровно тот класс, против которого сам же в этот день записал три нормы. > ⚠⚠ **Эррата 06.09-и (`D39.212` п.2/п.5/п.7 · `D39.213` п.6) — ЧЕТЫРЕ УТВЕРЖДЕНИЯ О ЧУЖОЙ РАБОТЕ, ИСТОЧНИК КОТОРЫХ — ПИСЬМО, А НЕ НОСИТЕЛЬ. Указал веер верификатора; статус проставляю я.** **(а)** «Зона ОТКАЗАЛАСЬ» на моё предложение (`D39.212` п.5) · «зона поймала ту же ошибку ОДНОВРЕМЕННО» (п.7) · «зона наткнулась на ту же ложную пробу НЕЗАВИСИМО» (`D39.213` п.6). Довод в зонных журналах есть, а вот ОДНОВРЕМЕННОСТЬ и НЕЗАВИСИМОСТЬ носителя не имеют: я взял их из канала. ⇒ **помечаю как сказанное зоной в канале, а не как установленное.** Утверждения о чужом ДЕЙСТВИИ ещё проверяемы по дереву; утверждения о чужом СОВПАДЕНИИ ВО ВРЕМЕНИ — почти нет, и потому их нельзя писать в акт тем же тоном. ⚠ Класс тот же, что 06.09-ж(б) и снятая клауза 06.09-д(в): **величина или факт из письма, поданные как из носителя** — третий и четвёртый раз за смену. **(б) А вот п.2 «снятие гварда проходило батарею ЗЕЛЁНОЙ» — ПРОВЕРЕН ЗАМЕРОМ, а не помечен.** Мутировал гвард в `if false` и прогнал пакет `runs` с ПРОПУЩЕННЫМ новым пином (`-skip`): **зелено, `exit=0`** ⇒ утверждение верно, без пина дефект не ловил никто. ⚠ **Усилено 06.09 по требованию верификатора: сначала здесь стояло «2 из 3», и это была АСИММЕТРИЯ** — красный прогон я отбросил как наблюдение, зелёный принял как свойство, оба из одной серии. Прогнана серия из ВОСЬМИ прогонов той же мутации с сохранением каждого лога: **8 из 8 `exit=0`, ноль падений**. Первый красный так и остался невоспроизведённым и необъяснённым (его лог утрачен), но против восьми зелёных он наблюдение, а не свойство — и теперь это сказано с обеих сторон, а не с одной. ⛔ **Но честности ради: из трёх моих прогонов этой мутации ПЕРВЫЙ дал КРАСНОЕ (48.8 с), и я едва не записал «батарея уже ловила это» — находку с ОДНОГО прогона.** Третий дал зелень, красное не воспроизвелось, лога первого я не сохранил ⇒ причина не установлена. Зарегистрированный флейк того же симптома есть (`PD-420`), но он в ДРУГОМ пакете, и приписывать ему я не стану. ⚠ Урок в свою сторону: **один красный прогон — не свойство, а наблюдение; я требую этого от зон и сам чуть не нарушил на проверке собственного акта.** > ⚠⚠ **Эррата 06.09-з (`D39.213` п.2 и п.3) — ТАБЛИЦА ТРЁХ ПРОГОНОВ ЧИТАЕТСЯ КАК КОНТРОЛИРУЕМОЕ СРАВНЕНИЕ, А БЫЛА ГОЛОСОВАНИЕМ 2:1 ПО ТРЁМ РАЗНЫМ КОНФИГУРАЦИЯМ — и это же описание ПРЯТАЛО мою сильнейшую улику. Нашёл верификатор; пере-проверено мной.** **(а) «Три прогона по ОДНОМУ дереву» — неверно.** Прогон (б) шёл по дереву с уже наложенной починкой, а она несла новый гейт-тест: в популяции `func Test` дерево ушло 849 → 850. **(б) Прогон (в) — ДО починки, а не после.** Мой чистый `go test` написан в **07:36:45**, эррата с его числами опубликована `be45500` в **07:38:50**, а починка `201363b` — в **08:04:37**. ⇒ группировать (б) и (в) как согласных против (а) значило выдавать за контроль то, что им не было. ⭐ **(в) ГЛАВНОЕ: контроль в таблице ЕСТЬ, и он другой.** Разложенные по признакам, а не по порядку: **(а)** до починки · лог ОБЩИЙ, зона гнала параллельно · **21/7**; **(в)** до починки · СВОЙ файл вне каталога зоны · **20/9**; (б) после починки · попрогонный · 20/9. **(а) и (в) — ОБА до починки и различаются расположением лога — и они расходятся.** ⇒ изолированная переменная — РАСПОЛОЖЕНИЕ ЛОГА, а не починка, и (б) не добавляет ничего сверх того, что (в) показал БЕЗ неё. **(г) Механизм предъявлен исполнением, а не правдоподобием** (проба верификатора, повторена мной в своей форме): два писателя, оба через `>` в один файл — как в старом рецепте, — дают **646 строк из 1200**, ОБЕ фракции в файле, 554 строки потеряны. То есть чужие строки появляются, а свои пропадают, и потеря асимметрична: ровно призрачный лишний пакет и спрятанные скипы. ⇒ **статус причины: НЕ догадка и НЕ замер — ВЫВОД, стоящий на до-починочном контроле и воспроизводимом механизме.** Тот конкретный случай невосстановим: лог стёрт самим прибором. ⚠ Урок формы: **один баннер накрыл две эпистемологии, и слабейшая из них была та, ради которой пункт написан.** Статус утверждения объявляется рядом с утверждением, а не общей шапкой на абзац. -> ⚠⚠ **Эррата 06.09-ж (эррата 06.09-г · `D39.212` п.6 · эррата 28.08-и) — ТРИ НЕПРАВДЫ, ВЪЕХАВШИЕ В КАНОН ТЕМ ЖЕ ДВИЖЕНИЕМ, КОТОРЫМ Я ИСПРАВЛЯЛ ПРЕДЫДУЩИЕ. Все три — в текстах ПРО СОБСТВЕННЫЕ ОШИБКИ; нашёл Fable 5 сверкой с деревом.** **(а) «Расщепление стояло ЧЕТВЕРО СУТОК» (эррата 06.09-г) — неверно: четыре с половиной ЧАСА.** `3e40c36` — 06.09 **03:00**, `1cae0ac` — 06.09 **07:30**. Полная история границы (`git log -L`, замер Fable, пере-проверен мной по датам коммитов): `f0d8fed` 08.08 02:26 ввёл `minimum: 1` ещё БЕЗ прозы о нуле · `278ffd8` 06.09 01:40 поставил `0` · `3e40c36` 03:00 вернул `1` · `1cae0ac` 07:30 вернул `0`. **Ни один отрезок не равен четырём суткам.** ⚠ Суть эрраты 06.09-г от этого не меняется — расщепление было, и написано оно одним заходом, — но ДЛИТЕЛЬНОСТЬ я не мерил, а написал по ощущению, и ощущение соврало в двадцать раз. **(б) `D39.212` п.6: «семь флагов, ШЕСТЬ ложных, настоящих два» — 6+2≠7; ложных ПЯТЬ.** Зонный журнал называет их поимённо (`target` · `RunRequest.chapters` · `.characters` · `character_count_exact` · `kind`), и пять плюс два дают семь. Число «шесть» я взял из ПИСЬМА зоны, не пересчитав, — при том что её собственный журнал держит верное. **Ровно класс эрраты 06.09-д: величина, перенесённая из чужого текста без пере-счёта, — и во второй раз за смену подряд.** ⚠ И арифметика была видна на месте: сумма не сходилась с итогом в той же фразе. **(в) «Код переехал вместе с ПЕРЕИМЕНОВАНИЕМ файла» (аннотация «испр. 06.09» внутри эрраты 28.08-и) — переименования не было.** `backend/internal/pipeline/seeding.go` ЖИВ и сегодня (128 строк); `bankmaterialize.go` **ДОБАВЛЕН** `6ec9f8a` 29.08, и в него код ВЫДЕЛЕН, а не переименован вместе с файлом. Верная причина, по которой линт не мог угадать адрес, — другая и проще: якорь был написан ГОЛЫМ именем, а голое имя отсеивается на `docs/scripts/counts.py:592`=`"~" in rel or "/" not in rel` ДО всякой проверки файла. Та же ложь стояла в строке 306 бэклога и там исправлена. ⚠ **Урок общий для всех трёх: текст про собственную ошибку пишется в тот момент, когда автор уверен, что уж ЭТО он знает, — и потому проверяется хуже обычного.** Ни одну из трёх не поймал бы ни один гейт: все три проза, и все три проверяемы одной командой, которую я не набрал. +> ⚠⚠ **Эррата 06.09-ж (эррата 06.09-г · `D39.212` п.6 · эррата 28.08-и) — ТРИ НЕПРАВДЫ, ВЪЕХАВШИЕ В КАНОН ТЕМ ЖЕ ДВИЖЕНИЕМ, КОТОРЫМ Я ИСПРАВЛЯЛ ПРЕДЫДУЩИЕ. Все три — в текстах ПРО СОБСТВЕННЫЕ ОШИБКИ; нашёл Fable 5 сверкой с деревом.** **(а) «Расщепление стояло ЧЕТВЕРО СУТОК» (эррата 06.09-г) — неверно: четыре с половиной ЧАСА.** `3e40c36` — 06.09 **03:00**, `1cae0ac` — 06.09 **07:30**. Полная история границы (`git log -L`, замер Fable, пере-проверен мной по датам коммитов): `f0d8fed` 08.08 02:26 ввёл `minimum: 1` ещё БЕЗ прозы о нуле · `278ffd8` 06.09 01:40 поставил `0` · `3e40c36` 03:00 вернул `1` · `1cae0ac` 07:30 вернул `0`. **Ни один отрезок не равен четырём суткам.** ⚠ Суть эрраты 06.09-г от этого не меняется — расщепление было, и написано оно одним заходом, — но ДЛИТЕЛЬНОСТЬ я не мерил, а написал по ощущению, и ощущение соврало в двадцать раз. **(б) `D39.212` п.6: «семь флагов, ШЕСТЬ ложных, настоящих два» — 6+2≠7; ложных ПЯТЬ.** Зонный журнал называет их поимённо (`target` · `RunRequest.chapters` · `.characters` · `character_count_exact` · `kind`), и пять плюс два дают семь. Число «шесть» я взял из ПИСЬМА зоны, не пересчитав, — при том что её собственный журнал держит верное. **Ровно класс эрраты 06.09-д: величина, перенесённая из чужого текста без пере-счёта, — и во второй раз за смену подряд.** ⚠ И арифметика была видна на месте: сумма не сходилась с итогом в той же фразе. **(в) «Код переехал вместе с ПЕРЕИМЕНОВАНИЕМ файла» (аннотация «испр. 06.09» внутри эрраты 28.08-и) — переименования не было.** `backend/internal/pipeline/seeding.go` ЖИВ и сегодня (128 строк); `bankmaterialize.go` **ДОБАВЛЕН** `6ec9f8a` 29.08, и в него код ВЫДЕЛЕН, а не переименован вместе с файлом. Верная причина, по которой линт не мог угадать адрес, — другая и проще: якорь был написан ГОЛЫМ именем, а голое имя отсеивается на `docs/scripts/counts.py:595`=`"~" in rel or "/" not in rel` ДО всякой проверки файла. Та же ложь стояла в строке 306 бэклога и там исправлена. ⚠ **Урок общий для всех трёх: текст про собственную ошибку пишется в тот момент, когда автор уверен, что уж ЭТО он знает, — и потому проверяется хуже обычного.** Ни одну из трёх не поймал бы ни один гейт: все три проза, и все три проверяемы одной командой, которую я не набрал. > ⚠ **Эррата 06.09-е (D39.211 п.1) — ТОТ ЖЕ НЕДОСЧЁТ ПАКЕТОВ УНАСЛЕДОВАН РАТИФИЦИРОВАННЫМ АКТОМ, А ТОЧНЫЙ РАЗБОР УЖЕ НЕВОССТАНОВИМ.** Пункт 1 цитирует числа зоны v13: «`MAKE-EXIT=2`, **21 пакет**, 20 ok». Пакетов у платформы **ДВАДЦАТЬ** — пере-считано 06.09 чистым `go test ./... -race -count=1 -v`: 20 различных, ни одного без тестов; список зона предъявила поимённо. ⇒ «21» здесь — то же, что в эррате 06.09-д: число СТРОК вывода, а не пакетов. ⛔ **А вот раскладка «20 ok» при `FAIL 1` — ⛔ **испр. 06.09 по находке верификатора: она НЕ БЫЛА УТРАЧЕНА, и ОБЕ причины, которыми я это объяснил, ложны.** **(а)** Раскладка лежала в зонном журнале — «ПАКЕТОВ 21: ok 20, FAIL 1» и «ТЕСТОВ верхнеуровневых 850: PASS 844 · FAIL 1 · SKIP 5» — **в ТОМ ЖЕ коммите `3327ac8`, которым эта эррата объявила её невосстановимой**: обвинение и улика заландены одним моим движением. **(б)** Прибор её не стирал: v13 был КРАСНЫМ (`MAKE-EXIT=2`), а рецепт до починки на красном пути выходит ДО `rm -f` и вслух обещает лог сохранить (`git show 201363b^:platform/Makefile`: `status -ne 0` ⇒ «the log is kept at .check.log» ⇒ `exit 1`, а `rm -f` достижим только на зелёном). Лог затёрт СЛЕДУЮЩИМ прогоном по фиксированному имени — другой механизм, и как раз тот, что чинился. ⇒ **снят и ⭐-вывод «цена дефекта строки 310, предъявленная не рассуждением, а СЛУЧАЕМ»: случая не было.** Сам дефект строки 310 реален, но иллюстрацию к нему я выбрал неверно дважды. ⚠⚠ **И худшее здесь не ошибка, а её форма: моя «реконструкция» (19 прошедших + 1 упавший + строка-дубль) угадала ВЕРНО — угадывая там, где лежал ЗАМЕР.** Пометка «это реконструкция, а не замер» выглядела осторожностью и ею не была: осторожность — это `git show` по собственному коммиту, а не оговорка при тексте. ⚠ Прочие числа пункта 1 под сомнение НЕ ставятся и подтверждены косвенно: «тестов 850» той же строки согласуется с ростом счёта на один после нового пина (`runs.TestABookWithNothingLeftIsRefusedRatherThanSoldAsAZeroChapterRun`) — ⚠ **довод ВЕРЕН, испр. дважды 06.09: я снял его по находке верификатора, а он находку отозвал, и отзыв верен.** В популяции прибора: `32a6050` — **850**, после ровно ОДНОГО пина `33b896b` — **851**. Ровно +1, ровно один пин. Прежнее снятие опиралось на счёт `func Test`, приложенный к числам другой популяции (`D39.202` п.2г). ⚠ И отдельно: «21 пакет из 21» в `D39.170` — НЕ ошибка и не трогается, там речь о батарее ДВИЖКА, у которого свой набор пакетов; проверено прежде, чем править. > ⚠⚠ **Эррата 06.09-д (D39.212 п.8) — ЧИСЛА ПРИЁМКИ, КОТОРЫЕ Я НАЗВАЛ СВОИМИ, СНЯТЫ ПРИБОРОМ С ДОКАЗАННЫМ ДЕФЕКТОМ, И ДВА ИЗ НИХ НЕВЕРНЫ.** **(а) Пакетов ДВАДЦАТЬ, а не 21.** 21 — это число строк `^ok`, среди которых `internal/money` напечатан ДВАЖДЫ; различных пакетов двадцать. ⭐ **Платформенная зона пришла к тому же числу ДРУГИМ путём** (у неё лишней была голая итоговая строка `FAIL` рядом со строкой упавшего ПАКЕТА) и поймала себя сама. То есть **одна и та же ошибка — величина, снятая с вывода прибора без разбора, что прибор печатает, — поймала обе стороны НЕЗАВИСИМО, в один час, на одном выводе**; это сильнее любого из двух наблюдений по отдельности. **(б) Скипов ДЕВЯТЬ, а не семь, и семь были не ошибкой счёта, а ложной уликой.** Число 7 снято из `make check`, чей лог живёт по фиксированному пути `platform/.check.log` и затирается параллельным прогоном (строка 310, дефект найден зоной в тот же час). ⛔ **Зона меня об этом предупредила, и я возразил «у меня обошлось — в моём логе нет ни одного `No such file`». Возражение было слабым: отсутствие СИМПТОМА не есть доказательство целости улики**, — и чистый пере-прогон это подтвердил. Строка 310 укусила ровно того, кто её завёл, в тот же час, что и завёл. **(в) Числа, снятые `go test ./... -race -count=1 -v` в файл ВНЕ каталога зоны:** `GO-EXIT=0` · **20 пакетов ok, ни одного без тестов** · верхнеуровневых прогонов **851 — и это верно для минуты прогона** (⚠ **испр. дважды 06.09.** Число было снято, а затем ВОЗВРАЩЕНО: верификатор нашёл «851 не существовало ни на одном коммите», я снял его на `44faafc`, после чего он сам же отозвал находку, и отзыв верен. **Пере-мерено мной ТРЕТЬИМ способом, чистыми экспортами `git archive`:** прибор считает верхнеуровневые ПРОГОНЫ вывода `go test -v`, а это `Test` **плюс `Fuzz`** — фаззер в обычном режиме гоняет сид-корпус и печатает `--- PASS: FuzzXxx`; у платформы таких таргетов два, и они стоят в моём же логе (`FuzzDecoder`, `FuzzSafeReturnTo`). Отсюда: `32a6050` 07:20 — 848+2=**850** · `93f098c` 07:33 — 849+2=**851** · `e92d411` 08:06 — 850+2=**852**. Лог написан 07:36, когда стоял `93f098c`, ⇒ **851 принадлежит настоящему коммиту**, и разложение 842 PASS + 9 SKIP сходится с деревом, а не только само с собой. На пине — **852**, разница ровно в гейт-тесте, заланденном `201363b`. ⛔ **Ошибка и находки, и моей проверки — ОДНА: сравнивались РАЗНЫЕ ПОПУЛЯЦИИ** — `func Test` против «верхнеуровневых прогонов», расходящиеся на два `Fuzz`. ⛔⛔ **И моя проверка не была проверкой: я пере-мерил ЕГО методом и потому воспроизвёл его ошибку, а не нашёл её.** Совпадение двух замеров доказывало лишь, что мы считаем одно и то же не то) · с подтестами PASS 1094 · `ALARM PD-count: 12 (baseline 12)`. ⛔ **Клауза «сошлось с зоной с двух сторон» СНЯТА 06.09 по находке верификатора.** Стояло: «у неё на тех же **851** — PASS 846 · SKIP 5, и разница ровно ЧЕТЫРЕ теста». **Зонный носитель этих чисел не держит ни в ту минуту, ни на пине:** `be45500` — «850: PASS 844 · FAIL 1 · SKIP 5», `e92d411` — «852: PASS 847 · FAIL 0 · SKIP 5». Числа пришли ПИСЬМОМ зоны, а я приписал их её ЖУРНАЛУ. **Тот же класс, что эррата 06.09-ж(б)** («шесть» взято из письма без пере-счёта) — в том же наборе эррат, в тот же час, и именно в клаузе, предъявленной как САМАЯ сильная улика набора. ⚠ Моя собственная норма «число называет ДЕРЕВО и ПОПУЛЯЦИЮ» поймала бы его: у этого числа не было ни того, ни другого. Разница между стендами реальна и объяснена гейтами стенда, но «двустороннее схождение» из неё не следует. **(г) Якорь п.6 был наведён на НЕУНИКАЛЬНЫЙ токен** и пере-наведён (`2ed1c0b`): `Structure *string` встречается в `v0.go` ДВАЖДЫ — `:216` (`wireBook`) и `:308` (`wireOrderOptions`), — так что скрипт мог сесть на чужое поле, а линт бы позеленел. Теперь `v0.go:306-308`=`null when no manifest`, токен по файлу единственный. ⇒ **уточнение к п.7 той же ноты: токен надёжнее номера строки только когда он УНИКАЛЕН. Неуникальный токен ХУЖЕ номера — номер врёт громко и ловится линтом, а он врёт молча и линт зеленит.** > ⚠⚠ **Эррата 06.09-г (эррата 06.09-в, клаузула (а)) — `minimum: 1` НАПИСАН НЕ ПО НЕЗНАНИЮ: ТЕМ ЖЕ ДВИЖЕНИЕМ Я СНЁС УЖЕ СТОЯВШИЙ ВЕРНЫЙ ОТВЕТ.** Эррата 06.09-в числит его ложью «второго захода» — это мягче факта. Дифф `3e40c36` (канон `0.12.0`, мой): в поле стояло `type: integer` + **`minimum: 0`** и абзац «`0` is legal and is not «nothing was ordered»: a re-pass buys no chapters and reports `0` here … A client that treats this as at-least-one will reject valid answers». **Коммит заменил `minimum: 0` на `minimum: 1` и в ТОМ ЖЕ заходе пере-написал абзац в сегодняшний «⚠ `0` is legal and means a re-pass … A client that treats this field as at-least-one will reject valid answers».** ⇒ знание не потеряно, а **РАСЩЕПЛЕНО: половина документа, которую читает человек, сохранила правду; половина, которую читает генератор клиента, получила ложь** — и они стояли в шести строках друг от друга **четыре с половиной часа** (⚠ испр. эрратой 06.09-ж: прежняя редакция писала «четверо суток» — длительность не измерялась вовсе). ⛔ Класс не «утверждение без прогона», а **регрессия против собственного канона**: неверное утверждение спорит с кодом и рано или поздно ловится, а снос верной гарантии уничтожает уже оплаченное знание — ровно то, о чём предупреждает шапка `CLAUDE.md`. ⚠ И это ЕЩЁ ОДНО свидетельство строки 309: гейт версии сверял числа, а документ противоречил сам себе внутри одного поля. ⭐ **Следствие для дофикса, снимающее с зоны половину работы:** сочинять нечего, верный ответ лежит в `git show 3e40c36^:docs/architecture/14-api-contract/openapi.yaml`; дело зоны — сверить его со своим пином и вернуть границу. ⚠ Соседний `minimum: 1` у `ordered_units` ВЕРЕН и не трогается: заказа на ноль юнитов не существует, а «заказан не юнитами» уже несёт `null`. @@ -2732,3 +2732,46 @@ $2.00» не мерил никто), **а утверждение о ПРОШЛО **7а. Состояние трёх выданных промтов на минуту передачи: НИ ОДНА сессия по ним НЕ СТАРТОВАЛА.** Это меняет форму правки: промт можно править ФАЙЛОМ. Если к моменту чтения сессия уже запущена — правка идёт дельтой по каналу, а файл под работающей сессией не переписывается. **8. ⭐ Что я сделал бы иначе.** Промты выдал мимо ДВУХ обязательных рубежей собственного ролевого промта, и поймал это не я. Замер границы беты настроил так, что опровергатели сняли все 14 блокеров — прибор отвечал на «есть ли обход?», а не на вопрос владельца. **Оба раза цена одна: я проверял чужое усерднее, чем своё.** + +## D39.218 — ЕДИНЫЙ БЭКЛОГ ВЫНЕСЕН В ОТДЕЛЬНЫЙ ФАЙЛ `docs/BACKLOG.md` (решение владельца, 06.09) ✅ + +**1. Решение владельца.** Таблица единого бэклога и её бюллетень живут ОТДЕЛЬНЫМ файлом +`docs/BACKLOG.md`; в `docs/PROGRESS.md` остаются CURRENT-STATE, состояние паков, живая хроника и +зонные секции «Бэкенд»/«Полигон». **ID строк не перенумерованы**: «строка N» ищется прежним грепом +`^| N |`, сменился только файл. + +**2. Что уехало и чем это доказано.** Легенда и таблица (строки 141–408 прежнего файла, 268 строк, +239 рядов) перенесены ПОБАЙТНО: дифф прежнего диапазона против хвоста нового файла пуст при 268 +сравнённых строках с обеих сторон. Бюллетень счёта уехал ВМЕСТЕ с таблицей — иначе гейт чисел тянул +бы шапку `PROGRESS` в каждый коммит таблицы (замер п.4). На прежнем месте оставлен заголовок-указатель +`## Бэклог`: ссылки «секция „Бэклог“» доезжают в один хоп, и `region()` по-прежнему режет шапку по нему. + +**3. Приборы переведены ТЕМ ЖЕ коммитом, иначе они молчат.** `counts.py` — константа `BACKLOG`, разбор +из нового файла, пять литералов бюллетеня. Зонный хук — третий носитель в триггере `--check`: без него +коммит, трогающий ТОЛЬКО таблицу, гейта не звал бы ровно там, где тот нужен. После правки `--check` +даёт 8 сходящихся проверок и те же числа, что на `ff14901` (239/113/158/105/0 · 458/106/major 3); +`--lint` — 0 проблемных якорей в 120 живых доках (было 119, плюс новый файл). + +**4. Замер, ради которого форма именно такая** (классификация 250 коммитов `docs/PROGRESS.md` с 25.08 +по секциям; прибор — пара-контролёр): голову трогали **167** коммитов, таблицу **148**, зонные секции +**66**; «только бэклог» — **48**. ⇒ вынос ОДНОЙ таблицы снимает **32 %** случаев ловушки «коммичу своё — +уношу чужое из того же файла», вместе с бюллетенем — **58 %**. Остальные 42 % трогают прозу шапки и +зонные секции; их лечит ДРУГОЙ вынос — строка бэклога **328**, она на владельце. + +**5. ⛔ ГРАНИЦА, ЗАМЕРЕННАЯ МУТАЦИЕЙ, А НЕ ВЫВЕДЕННАЯ.** Снятие заголовка `## Бэклог` гейт НЕ ловит — +и не ловил ДО выноса тоже: `backlog()` без заголовка сканирует файл целиком, а строк с числовым ID вне +секции не было ни там (0 при 239 внутри), ни здесь ⇒ счёт остаётся 239 и `--check` зелёный. ⚠ Первая +редакция этого пункта утверждала, что прежде в `PROGRESS` та же мутация краснела и вынос детекцию +ОСЛАБИЛ, — **утверждение снято**: пере-мер на HEAD-раскладке (`counts.py` + `PROGRESS` без заголовка) +дал «всего: 239», «сходятся», код 0. Ловится то, ради чего гейт и стоит: удаление ряда даёт +«✗ docs/BACKLOG.md: «всего **239** строк» против пере-счёта 238» и код 1; отсутствие файла — падение +с трассой, а не тихая зелень. **Класс ошибки — сравнение «до/после», где «до» не измерено, а +припомнено** (`D39.209` о том же с другой стороны). + +**6. Что тронуто СВЕРХ побайтного переноса — чтобы это не пришлось искать.** Пятнадцать живых +указателей своей зоны (README ×2 · glossary · три промта · `15-money-path` ×3 · `13-tech-debt-anchors` +×2 · `05-decisions-index` · `03-implementation-notes` · `06-memory-risk-registry` · `01-decisions`), +каждый — с ассертом единственности вхождения; улики (тела нот, `research/24` и `/25`, отчёт зоны в +`PROGRESS`, `DOC_CLEANUP_PLAN`) не тронуты намеренно. Плюс ЧЕТЫРЕ якоря на `counts.py`, которые сдвинул +этот же коммит (`:566`→`:569`, `:592`→`:595`): два из них стоят ВНУТРИ ячеек таблицы, то есть «ни одной +правки ячеек» — неверно, тронут ровно номер строки якоря. Поймал их линтер, а не глаз. diff --git a/docs/architecture/06-memory-risk-registry.md b/docs/architecture/06-memory-risk-registry.md index 3ae35f2e..9118e63e 100644 --- a/docs/architecture/06-memory-risk-registry.md +++ b/docs/architecture/06-memory-risk-registry.md @@ -100,7 +100,7 @@ ## Гейты для бэкенда перед фиксацией схемы store/глоссария v2 — ИСПОЛНЕНЫ -Список из пяти пунктов (F1-снапшот · поля `sense`/ось редакционного времени/`UNIQUE(src,sense,window)`/`min_key_len`/нормализация · обязательный post-check · трёхсторонний disposition + `retrieval-state` · отложенное в v1.1) закрыт стройкой и снят как план: схема — `backend/internal/store/migrate.go` (`sense`, `since_ch/until_ch`, `UNIQUE(book_id,src,sense,since_ch,until_ch)`, `allow_short` как escape-hatch к `min_key_len`), нормализация — `internal/text`, disposition CONFIRMED/AMBIGUOUS/REJECT и `retrieval-state` (`n_exact_hits, n_sticky, n_ambiguous_flagged, n_spoiler_blocked, n_evicted`) — `internal/membank` + `store/glossary.go`, **Палладий построен, Поливанова НЕТ** (⚠ испр. 02.09 — прежняя редакция засчитывала B6 целиком): Палладий — таблица-данные `backend/configs/langpacks/<пара>/palladius*.txt` через загрузчик `backend/internal/lang/langpack.go`, греп `pairFiles = []string{"palladius.txt"`, плюс алгоритм `backend/internal/miner/miner_palladius.go`, греп `buildPalladiusCyrSyllables` (D39.16); **Поливанов-валидатора в коде НЕТ** — таблицы Поливанова = данные ja-пары, которых в репо нет (улика и грепы — `docs/architecture/13-tech-debt-anchors.md`, срез строки 81, греп `Поливанов-валидатор`). Бэкап/интеграл файла книги (F4) тоже построен — `store.BackupSQLite`/`store.IntegrityCheck` + `tmctl backup` (хвост — в бэклоге `../PROGRESS.md`). Из отложенного НЕ построено (греп по `backend/` — 0 хитов): гейт фактичности резюме (D1 — резюме нет вовсе), whole-book эмбеддинг-слой (A7/D2 — горячий путь по-прежнему «no embeddings»), морфо-гейт глагольного рода (C3, Ф2). +Список из пяти пунктов (F1-снапшот · поля `sense`/ось редакционного времени/`UNIQUE(src,sense,window)`/`min_key_len`/нормализация · обязательный post-check · трёхсторонний disposition + `retrieval-state` · отложенное в v1.1) закрыт стройкой и снят как план: схема — `backend/internal/store/migrate.go` (`sense`, `since_ch/until_ch`, `UNIQUE(book_id,src,sense,since_ch,until_ch)`, `allow_short` как escape-hatch к `min_key_len`), нормализация — `internal/text`, disposition CONFIRMED/AMBIGUOUS/REJECT и `retrieval-state` (`n_exact_hits, n_sticky, n_ambiguous_flagged, n_spoiler_blocked, n_evicted`) — `internal/membank` + `store/glossary.go`, **Палладий построен, Поливанова НЕТ** (⚠ испр. 02.09 — прежняя редакция засчитывала B6 целиком): Палладий — таблица-данные `backend/configs/langpacks/<пара>/palladius*.txt` через загрузчик `backend/internal/lang/langpack.go`, греп `pairFiles = []string{"palladius.txt"`, плюс алгоритм `backend/internal/miner/miner_palladius.go`, греп `buildPalladiusCyrSyllables` (D39.16); **Поливанов-валидатора в коде НЕТ** — таблицы Поливанова = данные ja-пары, которых в репо нет (улика и грепы — `docs/architecture/13-tech-debt-anchors.md`, срез строки 81, греп `Поливанов-валидатор`). Бэкап/интеграл файла книги (F4) тоже построен — `store.BackupSQLite`/`store.IntegrityCheck` + `tmctl backup` (хвост — в бэклоге `../BACKLOG.md`). Из отложенного НЕ построено (греп по `backend/` — 0 хитов): гейт фактичности резюме (D1 — резюме нет вовсе), whole-book эмбеддинг-слой (A7/D2 — горячий путь по-прежнему «no embeddings»), морфо-гейт глагольного рода (C3, Ф2). ### Ruby-seed контракт (форма подтверждена оркестратором 05.07) diff --git a/docs/architecture/13-tech-debt-anchors.md b/docs/architecture/13-tech-debt-anchors.md index 38415ba0..8052a264 100644 --- a/docs/architecture/13-tech-debt-anchors.md +++ b/docs/architecture/13-tech-debt-anchors.md @@ -1,7 +1,7 @@ # Якоря техдолга — справочник к строкам бэклога (НЕ трекер) > **Часть находок ниже уже ЗАКРЫТА — закрытие помечено по месту D-номером, счёт закрытий в трекер не дублируется (D39.101).** -> **Единственный трекер — таблица «Бэклог» в `../PROGRESS.md`.** Этот файл — справочные file:line-якоря и скоуп-заметки к её строкам (вынесен из архива решением владельца — содержимое ЖИВОЕ). Актуализируется лендингами паков, которые трогают эти строки; исполненный пункт помечать ссылкой на D-номер, не удалять. +> **Единственный трекер — таблица «Бэклог» в `../BACKLOG.md`** (переехала из `PROGRESS.md` 06.09, D39.218; ID строк прежние). Этот файл — справочные file:line-якоря и скоуп-заметки к её строкам (вынесен из архива решением владельца — содержимое ЖИВОЕ). Актуализируется лендингами паков, которые трогают эти строки; исполненный пункт помечать ссылкой на D-номер, не удалять. > **Снятая мёртвая половина** (историческая улика ОТСУТСТВИЯ механизмов — снимок свипа 26.07–01.08 с file:line того времени) живёт носителем: `docs/archive/architecture/05-decisions-D39-59-90.md`, греп `D39.66-пост-сверка`; исполнение среза строки 25 — там же греп `D39.78`; закрытия банк-арки — `D39.69`. Здесь оставлен только ДЕЙСТВУЮЩИЙ статус. > ⚠ **Второй гвоздь под якоря НЕ строить — гейт уже построен и ратифицирован (D39.126):** `docs/scripts/counts.py --lint` сверяет якорь ПО СОДЕРЖИМОМУ через опт-ин токен `` `путь:123`=`подстрока` ``, органический остаток мигрируется на ЗАТРОНУТЫХ строках (бэклог-строка 205 — ЗАКРЫТА D39.200: гейт построен, миграция корпуса на токен-форму органическая и носителя больше не требует). Этот док — концентрат якорей, и органика на нём не сработала: токен-форму несут единицы, остальные гейт не видит ПО ПОСТРОЕНИЮ. Правильное действие — пакетная миграция якорей в токен-форму, не новый механизм. @@ -9,7 +9,7 @@ ### [RESCOPE ИСПОЛНЕН] Строка 81 — ja-преп B6-ja: Поливанов-валидатор + kana-омограф POS/known-word гейтинг (D17.1) + чек-лист kana-алиасов сида (D16.4) -Два компонента отсутствуют (полный состав и токен-якоря — строка 81 бэклога в `../PROGRESS.md`; здесь только отрицательная улика). **(1) Поливанов-валидатор:** валидирующего кода НЕТ — grep `polivanov`/`Поливанов` по `backend/**/*.go` даёт только значения конфига в тестах/примерах, коммент `Transcription` (`backend/internal/config/book.go`) и мост ruby-чтения (`backend/internal/membank/memseed.go`, греп `Polivanov bridge`, там же «B6, Phase 2»); поля схемы `translit_policy`/`ruby_reading` помечены «Phase 2» самим кодом. **(2) kana-омограф гейтинг** отложен явно: «KANA and HAN are deliberately NOT boundary-checked … their ≥4 precision is deferred to the kana-precision measurement + the B6 tokenizer» (`backend/internal/membank/memory.go`), подтверждено D17 (тело — слайс `D1-D38`: митигация kana-омографов → «скоуп B6»). **Третий компонент — чек-лист kana-алиасов сида (D16.4) — ПОСТРОЕН** (`backend/README.md` §ja + `AttachRubyAliasesToManual`); в чек-листе остался лишь Ф2-хвост «двойные чтения (強敵→とも) полная дизамбигуация», и он тоже под B6. +Два компонента отсутствуют (полный состав и токен-якоря — строка 81 бэклога в `../BACKLOG.md`; здесь только отрицательная улика). **(1) Поливанов-валидатор:** валидирующего кода НЕТ — grep `polivanov`/`Поливанов` по `backend/**/*.go` даёт только значения конфига в тестах/примерах, коммент `Transcription` (`backend/internal/config/book.go`) и мост ruby-чтения (`backend/internal/membank/memseed.go`, греп `Polivanov bridge`, там же «B6, Phase 2»); поля схемы `translit_policy`/`ruby_reading` помечены «Phase 2» самим кодом. **(2) kana-омограф гейтинг** отложен явно: «KANA and HAN are deliberately NOT boundary-checked … their ≥4 precision is deferred to the kana-precision measurement + the B6 tokenizer» (`backend/internal/membank/memory.go`), подтверждено D17 (тело — слайс `D1-D38`: митигация kana-омографов → «скоуп B6»). **Третий компонент — чек-лист kana-алиасов сида (D16.4) — ПОСТРОЕН** (`backend/README.md` §ja + `AttachRubyAliasesToManual`); в чек-листе остался лишь Ф2-хвост «двойные чтения (強敵→とも) полная дизамбигуация», и он тоже под B6. ### [ЗАКРЫТО D39.82] Строка 83 — F4: бэкап + integrity_check SQLite перед платным прогоном (VACUUM INTO) → **ИСПОЛНЕНО D39.82: `tmctl backup` + pre-flight (`backend/cmd/tmctl/backup.go`, коммит `9f60746`; команда `backup` в `dispatchCommands`), строка 83 закрыта; остаток F4-хвоста — строка 93** @@ -142,7 +142,7 @@ Go-гейт стоит на v1 без поглощения кавычек: backe ## Архео-хвосты жирных строк бэклога (выселение докс-паком строки 167, 09.08.2026) -> Тела ячеек «Хвост» перенесены сюда ДОСЛОВНО на момент выселения (норма D39.125 п.3: «диспозиция сверху, археология вниз»; ячейка >800 байт — не трекер). Живая диспозиция каждой строки — ТОЛЬКО таблица бэклога `../PROGRESS.md`; здесь справочная археология. Закрытия помечать по месту стрелкой «→ Dxx», не удалять. +> Тела ячеек «Хвост» перенесены сюда ДОСЛОВНО на момент выселения (норма D39.125 п.3: «диспозиция сверху, археология вниз»; ячейка >800 байт — не трекер). Живая диспозиция каждой строки — ТОЛЬКО таблица бэклога `../BACKLOG.md`; здесь справочная археология. Закрытия помечать по месту стрелкой «→ Dxx», не удалять. > ⚠ **Голые `file.go:NNN` в этой секции — снимок 09.08.2026, и часть номеров с тех пор съехала (сверено 02.09).** Сверяйся ГРЕПОМ по названной функции/константе/цитате, а не по номеру строки; пере-нацеленный якорь пиши токен-формой `` `путь:123`=`подстрока` ``. ### Б-13б — тело строки 13б на 09.08.2026 diff --git a/docs/architecture/15-money-path.md b/docs/architecture/15-money-path.md index 45c2b107..ddf0395b 100644 --- a/docs/architecture/15-money-path.md +++ b/docs/architecture/15-money-path.md @@ -22,7 +22,7 @@ - **`--ceiling-usd` — КНИЖНЫЙ потолок, не бюджет прогона.** Дословно из флага: «the book USD ceiling in force for THIS RUN ONLY — it OVERRIDES book.yaml `ceilings.book_usd` and is never written back. It caps the book's CUMULATIVE committed+reserved spend, not this run's increment…» (`backend/cmd/tmctl/invocation.go:142`=`the book USD ceiling in force for THIS RUN ONLY`; ⚠-коммент `backend/cmd/tmctl/main.go:260`=`--ceiling-usd is NOT a per-run budget`; многоточие закрывает обрыв цитаты — во флаге дальше стоит «, and must be > 0»). Ратификация — D39.122 п.2(в): пересчёт «пользовательский прирост → абсолют» — обязанность ПЛАТФОРМЫ, вторая денежная ось не заводится. День-потолок флаг НЕ перекрывает (PD-157). Проводка внутри: `Ceilings.BookUSD` в `Reserve` и именование сработавшего потолка в ошибке — `backend/internal/pipeline/stagerun.go:495`=`BookUSD: r.bookCeilingUSD()` и `backend/internal/pipeline/stagerun.go:559`=`overrides the book's ceilings.book_usd` (стоп = `errReserveCeiling`, `backend/internal/pipeline/escalation.go:49`=`var errReserveCeiling`). - **Потолки — wiring, не семантика:** `Ceilings` намеренно исключены из `BriefHash` («Wiring fields (paths, ceilings, db) deliberately excluded», `backend/internal/config/book.go:345`=`Wiring fields (paths, ceilings, db) deliberately excluded`; канон — `backend/internal/config/book.go:369`=`canon := struct {`) ⇒ смена ДЕНЕЖНОГО потолка не двигает ни снапшот, ни ре-билл (D39.110 п.2б). ⚠ Верно ровно про ДЕНЬГИ: потолок СЕГМЕНТАЦИИ `edit_ceiling_out` в снапшот ВХОДИТ и меняет границы чанков (`backend/internal/pipeline/snapshot.go:34`=`EditCeilingOut int`). - **`status --json` отдаёт фигуры платформе:** `committed_usd`, `reserved_usd`, `book_ceiling_usd`, `ceiling_pct` = 100·(committed+reserved)/book_ceiling (`backend/internal/pipeline/status.go:311`=`book_ceiling_usd,omitempty`; арифметика `ceiling_pct` — `backend/internal/pipeline/status.go:869`=`100 * (committed + reserved)`). Дневной фигуры в status нет (PD-157 — `platform/docs/DEFECT_REGISTER.md`, греп `PD-157`). -- **Леджер = НИЖНЯЯ граница** (строка 78 бэклога, `docs/PROGRESS.md`, греп `Леджер денег = НИЖНЯЯ граница`): «2xx body decode failed (call IS billed)» — провайдер списал, попытка в `request_log` не попадает; живой замер D39.86 — 3 вызова из 14, неизвестность $0.015111 при леджере $0.114378; движок сеттлит оценку и печатает `estimated-cost rows: 3`. Канал виден, фикс — money-паком (дизайн GENERALITY_PHASE2 §5.6). +- **Леджер = НИЖНЯЯ граница** (строка 78 бэклога, `docs/BACKLOG.md`, греп `Леджер денег = НИЖНЯЯ граница`): «2xx body decode failed (call IS billed)» — провайдер списал, попытка в `request_log` не попадает; живой замер D39.86 — 3 вызова из 14, неизвестность $0.015111 при леджере $0.114378; движок сеттлит оценку и печатает `estimated-cost rows: 3`. Канал виден, фикс — money-паком (дизайн GENERALITY_PHASE2 §5.6). - **Согласие на пере-оплату — ДВИЖКОВЫЙ гейт**. Прогон, который пере-покупает уже оплаченные юниты дороже порога, ОСТАНАВЛИВАЕТСЯ и требует явного согласия. Порог по умолчанию ратифицирован D20.2-Q2: `min($0.50, 5% × ProjectedBookUSD)`. Носитель — `backend/internal/pipeline/rebill.go`, греп `rebillConsentThreshold`; единственная ручка книги — `rebill_consent_usd` (валидатор `backend/internal/config/book.go`, греп `rebill_consent_usd`; 0 = ратифицированный дефолт). ⚠ Порог считается БЕЗ контура банк-ролей (D39.182 §3), то есть срабатывает позже, чем подсказывает полная проекция. @@ -49,7 +49,7 @@ 8. **Settle по фигуре движка.** `reconcile.settle` (`platform/internal/runs/reconcile.go`, греп `func (s *Service) settle(` — ⚠ номера строк в файлы живой зоны не ставим, пока её сессия работает) читает committed из status; `credits.Settle` одной транзакцией закрывает резервацию, возвращает холд и списывает spent; **spent > холда — капится холдом** с явной пометкой «capped at the hold; the engine reported …» (`platform/internal/pgstore/credits.go`, греп `capped at the hold; the engine reported`), перерасход движка счётом не абсорбируется. 9. **SpendBound (PD-159).** Отложенный settle читает пожизненный счётчик КНИГИ и без границы оплатил бы работу прогона-преемника (замер: $2.10 за прогон ценой $0.10, и преемник платил снова). Граница = наименьший baseline попыток той же книги, стартовавших ПОЗЖЕ: `committed = min(счётчик сейчас, SpendBound)` (`platform/internal/runs/reconcile.go`, греп `bound != nil`; `platform/internal/pgstore/runs.go`, греп `func (s *Store) SpendBound(`). -10. **Открытое — эскроу/intent (строка 136 бэклога, `docs/PROGRESS.md`, греп `Write-ahead intent`):** write-ahead intent + состояние `uncertain`-эскроу + `closing`; холд НЕ освобождается по выходу юнита (сигнал обгоняет денежные события); spend не постится без свидетельства провайдера; расход сверх холда — полной суммой, превышение явной строкой убытка. Стройка по research/25, «скоро». ⚠ **«Строка 103» — ФАНТОМ, снят 31.08:** такой строки в бэклоге нет (закрыта D39.131), а эмиттер шва ПОСТРОЕН с обеих сторон — платформа тейлит `events.jsonl` и принимает кадр `spend` (`platform/internal/ingest/events.go`, греп `TypeSpend Type`). Денежной слепоты это НЕ снимает по построению: поток событий — только свежесть. Платформа между спавном и settle слепа — защита держится холдом и потолком движка (§1). +10. **Открытое — эскроу/intent (строка 136 бэклога, `docs/BACKLOG.md`, греп `Write-ahead intent`):** write-ahead intent + состояние `uncertain`-эскроу + `closing`; холд НЕ освобождается по выходу юнита (сигнал обгоняет денежные события); spend не постится без свидетельства провайдера; расход сверх холда — полной суммой, превышение явной строкой убытка. Стройка по research/25, «скоро». ⚠ **«Строка 103» — ФАНТОМ, снят 31.08:** такой строки в бэклоге нет (закрыта D39.131), а эмиттер шва ПОСТРОЕН с обеих сторон — платформа тейлит `events.jsonl` и принимает кадр `spend` (`platform/internal/ingest/events.go`, греп `TypeSpend Type`). Денежной слепоты это НЕ снимает по построению: поток событий — только свежесть. Платформа между спавном и settle слепа — защита держится холдом и потолком движка (§1). ## 4. Фронт (зона `frontend/`) @@ -77,7 +77,7 @@ | Ратификации, на которых стоит этот док | ⚠ **добавлены 05.09: `D39.203`** (владелец: движку МОЖНО говорить «сколько добавить»; наружу идёт ДО-ВЫЗОВНАЯ ОЦЕНКА, не стоимость) · **`D39.204`** (отказ резервации на ретрае деградирует во ФЛАГ; решение принято, код НЕ тронут — строка 291) · **`D39.206`** (акт приёмки денежного стопа). ⚠ **И новые движковые денежные носители того же лендинга:** `backend/internal/pipeline/reservegate.go` (шлюз резерваций и `shortfallMicroUSD`) · `priceprojection.go` (проекция цены книги) · `internal/runevents/runevents.go` (`Ceiling.ShortfallMicroUSD`, `Finished.Money`, поток 1.3). · **D39.179** (пере-пин цен 16.08, ×4.47; норма «стабилен чистый ФАЙЛ» — п.4) · **D39.181** (закон раскрытия: признак объёмного стопа едет числом) · **D39.182** (пак «деньги и честность»: план банк-ролей режется до первого вызова; порог согласия без контура банк-ролей) | | Код денег движка | `backend/internal/store/ledger.go` · `store/store.go` · `pipeline/stagerun.go` · `pipeline/status.go` · `config/book.go` · `pipeline/rebill.go` (согласие на пере-оплату) · `pipeline/terminologist.go` (книго-широкие бюджеты банк-ролей) · `pipeline/volume.go` (объёмный потолок) | | Дефекты денег | `platform/docs/DEFECT_REGISTER.md` (PD-104·113·144·157·158·159) | -| Бэклог-строки | `docs/PROGRESS.md` строки 78 · 136 · 137 (⚠ испр. 05.09: **166 отсюда СНЯТА** — движковая половина оценки построена и опубликована лендингом `81a89e9`; открыта только платформенная) (135 и 165 закрыты D39.131) | +| Бэклог-строки | `docs/BACKLOG.md` строки 78 · 136 · 137 (⚠ испр. 05.09: **166 отсюда СНЯТА** — движковая половина оценки построена и опубликована лендингом `81a89e9`; открыта только платформенная) (135 и 165 закрыты D39.131) | | Контракт наружу | `14-api-contract/openapi.yaml` (⚠ **`CeilingBounds` РЕТИРОВАН лендингом формы заказа 06.09** — его место занял `RunOptions` с `chapters_left`/`affordable_chapters`/`verdict` и денежными границами; `Usage`); ПТ-35 | | ⚠ Запрет денег на экране — **ОТОЗВАН 05.09 (D39.196)**. Живым остаётся ПТ-35 в его четырёх пунктах: цены моделей · стоимость стадий · стоимость ВЫЗОВОВ · структура наших расходов. ⚠ И различение `D39.203`, без которого пункт про вызовы читается неверно: наружу идёт ДО-ВЫЗОВНАЯ ОЦЕНКА (резервация перед звонком), а запрет написан про СТОИМОСТЬ — что списано по факту; сеттлмент не выходит | D39.84; D39.100/К-8; ПТ-35; **D39.196**, эррата 05.09-а | diff --git a/docs/glossary.md b/docs/glossary.md index c326d395..6368fc72 100644 --- a/docs/glossary.md +++ b/docs/glossary.md @@ -25,7 +25,7 @@ - **Харнесс** — обвязка исполнения (наш пайплайн-транспорт или конкурентные agent-обвязки; калибровка — research/21–22). - **⚠-баннер** — шапка «тело superseded, чему верить»; **ревью-шапка** — вердикты приёмки поверх отчёта в `archive/reports/`. - **Пак** — пакет работ одной сессии; **свип** — полная перепроверка обязательств (D39.66: 951 позиция); **добор идеала** — очередь качества после ре-пробы flash; **МАСШТАБ** — прогон целой книги. -- **Строка N** — стабильный ID строки единого бэклога (PROGRESS §Бэклог; не перенумеровывается); **вес** — блокер-очереди / скоро / когда-нибудь; **носитель** — артефакт, в котором обязательство живёт; **хвост** — незакрытый остаток; **петля** — вопрос, обязанный получить диспозицию; **слот** — зарезервированное место в будущем пакете/замере. +- **Строка N** — стабильный ID строки единого бэклога (`docs/BACKLOG.md`; не перенумеровывается); **вес** — блокер-очереди / скоро / когда-нибудь; **носитель** — артефакт, в котором обязательство живёт; **хвост** — незакрытый остаток; **петля** — вопрос, обязанный получить диспозицию; **слот** — зарезервированное место в будущем пакете/замере. - **Гвоздь** — регрессионный тест, прибивающий контракт (негативный гвоздь — тест на ОТСУТСТВИЕ поведения). - **Реестр 108 / «жилец реестра»** — строка 108 единого бэклога: реестр ЗАГЕЙЧЕННЫХ ТРИГГЕРОВ (отложенных реопенов с условием «когда вернуться»); «жилец» = такой реопен; норма «каждое отложено получает строку или жильца» — D39.66/D39.90. - **Контракт 14 (API v0)** — ратифицированный контракт фронт↔платформа: `architecture/14-api-contract/` — нормативная спека OpenAPI 3.1 + компаньон-README; зонная копия `frontend/docs/api-contract/` — байт-зеркало (D39.99; статус зеркала и версий — карта `README.md`, здесь не пинятся). **Провенанс ✓/◆/○** — классы утверждений компаньона: выведено из кода/ратификации · предложено (подтверждает названная зона) · открыто (К-вопросы). **spectral / openapi-typescript** — линт спеки и генерация типов фронта с дрифт-тестом (⚠ 3.1-условия генератор игнорирует — К-11). diff --git a/docs/scripts/counts.py b/docs/scripts/counts.py index a85e2a95..434f22b8 100644 --- a/docs/scripts/counts.py +++ b/docs/scripts/counts.py @@ -47,6 +47,9 @@ from pathlib import Path ROOT = Path(__file__).resolve().parents[2] PROGRESS = "docs/PROGRESS.md" +# ⚠ Таблица бэклога и её бюллетень живут ОТДЕЛЬНЫМ файлом с 06.09 (D39.218); в PROGRESS на +# прежнем месте стоит заголовок-указатель, поэтому `region()` по-прежнему режет шапку по нему. +BACKLOG = "docs/BACKLOG.md" DLOG = "docs/architecture/05-decisions-log.md" REGISTER = "platform/docs/DEFECT_REGISTER.md" NOTE_INDEX = "docs/architecture/05-decisions-index.md" @@ -323,14 +326,14 @@ def head(dlog: str, prog: str, idx: str) -> dict: # ненайденный литерал = проверка перестала проверять, и это докладывается как расхождение. # region ограничивает поиск, чтобы историческая секция со старым числом не давала ложной тревоги. LITERALS = [ - (PROGRESS, "current-state", r"всего \*\*(\d+)\*\* строк", ("backlog", "всего")), - (PROGRESS, "current-state", r"зона бэкенд \*\*(\d+)\*\* строго", ("backlog", "бэкенд строго")), - (PROGRESS, "current-state", r"/ \*\*(\d+)\*\* широко", ("backlog", "бэкенд широко")), - (PROGRESS, "current-state", r"«скоро» \*\*(\d+)\*\*", ("backlog", "скоро")), + (BACKLOG, "current-state", r"всего \*\*(\d+)\*\* строк", ("backlog", "всего")), + (BACKLOG, "current-state", r"зона бэкенд \*\*(\d+)\*\* строго", ("backlog", "бэкенд строго")), + (BACKLOG, "current-state", r"/ \*\*(\d+)\*\* широко", ("backlog", "бэкенд широко")), + (BACKLOG, "current-state", r"«скоро» \*\*(\d+)\*\*", ("backlog", "скоро")), # ⚠ Добавлено 23.08 (оркестратор №19): пятое число ТОЙ ЖЕ фразы очереди скрипт считал и печатал, # но НЕ сравнивал, и другого гарда на него в репозитории не было — «блокеров 0» могло разойтись # с таблицей молча. Литерал не обёрнут своими `**` — жирным помечена вся фраза целиком. - (PROGRESS, "current-state", r"блокеров очереди (\d+)\*\*", ("backlog", "блокеров очереди")), + (BACKLOG, "current-state", r"блокеров очереди (\d+)\*\*", ("backlog", "блокеров очереди")), # ⚠ Литерал веса регистра СНЯТ с проверки 08.08, и это не упрощение, а исправление ошибки # проектирования: единственным его носителем в зоне docs была ИСТОРИЧЕСКАЯ фраза о том, что нашла # приёмка, а гард требовал от неё равенства ТЕКУЩЕМУ пере-счёту регистра. Первый же фикс зоны @@ -694,7 +697,8 @@ def main() -> int: return 1 if problems else 0 dlog, prog, reg = read(DLOG), read(PROGRESS), read(REGISTER) - b, r, h = backlog(prog), register(reg), head(dlog, prog, read(NOTE_INDEX)) + bck = read(BACKLOG) + b, r, h = backlog(bck), register(reg), head(dlog, prog, read(NOTE_INDEX)) check = "--check" in sys.argv src = "содержимое коммита (индекс/HEAD)" if FROM_INDEX else "рабочее дерево" @@ -734,7 +738,7 @@ def main() -> int: f"максимум по номеру {h['максимум по номеру']} — голова считается по максимуму" ) - texts = {PROGRESS: prog, REGISTER: reg} + texts = {PROGRESS: prog, REGISTER: reg, BACKLOG: bck} for path, reg_name, pattern, (kind, key) in LITERALS: if kind == "backlog": want = b[key] diff --git a/docs/scripts/githooks/pre-commit b/docs/scripts/githooks/pre-commit index 0e34ee26..df0f89d9 100755 --- a/docs/scripts/githooks/pre-commit +++ b/docs/scripts/githooks/pre-commit @@ -38,6 +38,9 @@ staged=$(git diff --cached --name-only) dlog='docs/architecture/05-decisions-log.md' prog='docs/PROGRESS.md' +# ⚠ Третий носитель с 06.09 (D39.218): таблица бэклога и её бюллетень уехали в отдельный файл, +# и без него `--check` не звали бы РОВНО на тех коммитах, что меняют таблицу. +backlog='docs/BACKLOG.md' # ⚠ БЫСТРОГО ВЫХОДА ПО «коммит не задевает docs/» БОЛЬШЕ НЕТ (21.08, разбор с внешним ревьюером). # Он ампутировал ЦЕЛЕВУЮ сторону дельта-сверки якорей: якорь протухает, когда двигается ЦЕЛЬ, а цели @@ -71,7 +74,7 @@ fi # 2) Производные числа — по содержимому коммита, и ТОЛЬКО когда в коммите носители этих чисел # (гейтовка прежняя, D39.112). Ненайденный литерал скрипт тоже считает расхождением: проверка, # молча перестающая проверять, хуже отсутствующей. -if printf '%s\n' "$staged" | grep -qE "^($dlog|$prog)$"; then +if printf '%s\n' "$staged" | grep -qE "^($dlog|$prog|$backlog)$"; then if command -v python3 >/dev/null 2>&1 && [ -f docs/scripts/counts.py ]; then if ! out=$(python3 docs/scripts/counts.py --check --from-index 2>&1); then echo "pre-commit ⚠ docs: производные числа разошлись с пере-счётом:" >&2