From 40730551e11cb5035a518f2988a3e033f5b05ea4 Mon Sep 17 00:00:00 2001 From: heaven Date: Wed, 2 Sep 2026 15:47:04 +0300 Subject: [PATCH] Apply the controller's dofix in the docs zone: restore what the cut lost and repair what it broke, including places where the text asserted the wrong thing about the code --- docs/PROGRESS.md | 23 ++++++++++++-------- docs/architecture/02-mvp-plan.md | 2 +- docs/architecture/03-implementation-notes.md | 2 ++ docs/architecture/05-decisions-log.md | 3 +++ docs/architecture/06-memory-risk-registry.md | 2 +- docs/architecture/10-prompt-architecture.md | 2 +- docs/architecture/13-tech-debt-anchors.md | 6 ++--- docs/architecture/14-api-contract/README.md | 2 +- docs/architecture/15-money-path.md | 2 +- docs/architecture/16-events-emitter.md | 4 ++-- 10 files changed, 29 insertions(+), 19 deletions(-) diff --git a/docs/PROGRESS.md b/docs/PROGRESS.md index 680035a7..4a65762f 100644 --- a/docs/PROGRESS.md +++ b/docs/PROGRESS.md @@ -1,6 +1,6 @@ # Журнал прогресса -> **⟶ ТЕКУЩЕЕ СОСТОЯНИЕ** (на 2026-09-01, голова D39.185 — КУРС: движок и платформа до «работает и отдаёт результат», фронт ЗАМОРОЖЕН и P7 его НЕ размораживает (D39.147). **ОЧЕРЕДЬ №22** (единственный носитель — здесь; роль передана 01.09, №21 закрыт нотой передачи D39.184). ⚠ **ЗАКАЗ ВЛАДЕЛЬЦА 01.09 — ПЕРВЫМ:** (0а) **ревизия документации на ПРОТУХШЕЕ** — по всем зонам, не только тронутым; (0б) **планы доработок в БЭКЕНД и ПЛАТФОРМУ** по остатку бэклога и регистра; (0в) **вынос неактуального в АРХИВ** (`docs/archive/`, `platform/docs/archive/`) — за сутки 31.08 закрыто много, и часть носителей стала историей. ⚠ Трезвость по масштабу (пере-считано 02.09): **88** живых доков в `docs/` против **198** заархивированных, 8 в `platform/docs`, 9 в `backend/docs` — ⚠ из 88 три ВРЕМЕННЫЕ (`DOC_CLEANUP_PLAN` · `DOC_REVISION_FINDINGS` · `DOC_REVISION_REFUTED`), они уедут в архив по закрытии разбора, то есть постоянных **85**; счёт бэклога — бюллетенем ниже, открытых рядов регистра платформы — 97 (major 2) ⚠ (ревизией 02.09 ряды **154** и **157** переведены из «скоро» в «когда-нибудь»: их гейтом стоял первый холодный прогон, он ОТРАБОТАЛ 31.08 и оба предусловия оказались другими — разбор в самих ячейках, ни одна НЕ закрыта). ⚠ Числа доков `counts.py` НЕ сторожит — при переносе файлов пере-считывать руками командой `find docs -name '*.md' -not -path 'docs/archive/*' | wc -l`. ⚠ И предупреждение о МЕТОДЕ, купленное сменой №21: «выглядит протухшим» ≠ «протухло». Три факта оркестратора опровергнуты ЗАМЕРОМ сессий, а якоря `15-money-path.md` в девяти случаях из двенадцати РОДИЛИСЬ верными и сгнили дрейфом — то есть ревизия обязана быть исполнением, а не чтением. ⚠ **ОЧЕРЕДЬ, унаследованная от №21** (⚠ **пак P12 ПРИНЯТ И ЗАЛЕНДЖЕН 31.08 — D39.180**, вместе с контрактным минором **0.9.0**; `PD-425` закрыт им же. ⚠ **ДВА ЛЕНДИНГА 31.08:** бэкенд-пак **«ДЕНЬГИ И ЧЕСТНОСТЬ ВЫДАЧИ» — D39.182** (счёт линз, блокеров и урок «дефект в самом лекарстве» — телом ноты; тестов 1045→1083, удалённых ноль) и ратифицированный владельцем **ЗАКОН РАСКРЫТИЯ движка — D39.181**, применённый к одиннадцати экземплярам): **(1) РАЗРЫВ ЦИКЛА: книга не отдаётся файлом ПОЛЬЗОВАТЕЛЮ — открыта ПЛАТФОРМЕННАЯ половина.** Движок пишет файл с 30.08 (`tmctl build` — EPUB 3 + чистый txt, D39.175), и холодный прогон 31.08 предъявил это живьём: собранный EPUB настоящего перевода прошёл `epubcheck` 0/0/0/0 и передан владельцу. Открыто ровно одно: канон обещает `createExport`/`getExport`, а платформа их НЕ монтирует (смонтировано 15 операций из 20; нет также `getRun`, `updateBook`, `deleteBook`). Долг числится с P8 (`platform/BACKLOG.md` П-17), и НИ ОДИН пак платформы после P7 его не взял (проверка вместо ручного счёта, чтобы не гнило при каждом лендинге: `grep -rn 'createExport\|getExport' platform/internal/ --include=*.go` — пусто). **Слово «отдаёт результат» ложно по букве ТОЛЬКО платформенной половиной** (п.4) · **(2) ~~холодный прогон движка~~ ОТРАБОТАЛ 31.08, закрыт РЕШЕНИЕМ ВЛАДЕЛЬЦА «не доводить»** (отчёт — `archive/reports/COLDRUN_V16_REPORT_2026-08-31.md`, числа относятся к `065d8ac`). Потрачено **$0.436110** из санкции $0.80. ПРЕДЪЯВЛЕНО живьём: объёмный потолок · D39.158 ОБЕИМИ половинами (стоп и не-стоп) · exit 16 · строки 154/198/239/240. ⚠ **Причина большой доли редактора НЕ УСТАНОВЛЕНА** — три каузальные истории построены и две сняты. Доля редактора идёт с ДВУМЯ знаменателями: **49.3%** от всего прогона ($0.214865 из $0.436110) и **81.3%** внутри порции П1 (⚠ ходившее «73%» — фантом, в отчёте его нет ни разу). Следующий шаг — контролируемая проба по ЧЕТЫРЁМ осям (§14 отчёта): трудность чанка БЛОКИРОВАТЬ, длину входа КОНТРОЛИРОВАТЬ, промпт по SHA, эффорт `off` против `low`. Ось `stale` НЕДОСТИЖИМА (под дрейфом `staleUnits` возвращает UNKNOWN немедленно). ⚠ **Цена: слово владельца 31.08 — ≈$0.60, потолок $0.80, ДЕСЯТЬ глав ПОЛНОЙ цепью включая редакторскую волну.** ⚠ **ГЕЙТ КЛЮЧЕЙ СНЯТ словом владельца 30.08** (D39.176 п.6), но конвенционного `.env` НЕТ НИ У ОДНОЙ книги корпуса — прогон обязан передавать `--keys-file` абсолютным путём; заполнены только `projects/textmachine/backend/.env` и `.../eval/.env`. ⚠ Для п.3 нужен ДРУГОЙ файл — путь платформы `TM_PLATFORM_ENGINE_KEYS_PATH`. **Вопрос владельцу СНЯТ 31.08 вычитанием инженерной половины:** формат обоих файлов совпадает (`KEY=VALUE`), переменная требует АБСОЛЮТНОГО пути (`platform/internal/config/config.go`, греп `must be an absolute path`), едет `--keys-file` и только на `translate`; заполненный файл на машине существует. Лечение операционное и $0 — направить переменную на него; проверять ПРОГОНОМ, не чтением (гардрейл `.env`) · **(3) живой сквозной прогон через API платформы** — форма манифеста, сайдкара банка и карта причин флагов сочинены платформой САМОСТОЯТЕЛЬНО. ⚠ Уточнено 01.09: гейт СНЯТ холодным прогоном, и настоящие артефакты движка теперь ЕСТЬ (каталог `books/gu-zhenren/coldrun-v16/`), но сверка вышла ТОНКОЙ: на шов реально вышло **одно значение `flag_reason` из пятнадцати** (`sanitizer_stripped`), остальные четырнадцать по-прежнему только чтением кода, а манифест против `platform/internal/ingest/manifest.go` не сверялся вовсе · **(4) дверь выдачи** — строго ПОСЛЕ (3) (⚠ слово владельца 30.08: дверь ВСЕГДА строит файл — отказ юзеру не отдаётся, неполная книга уходит с пометкой, т.е. дверь зовёт `tmctl build --partial`; отказ по умолчанию остаётся операторской ручкой CLI; D29.1(б) «fail-closed» читать как «никогда молча» — честность несут пометки) · **(5) проводка `--max-units`** — снятие гейта, а не стройка: механизм в движке стоит (D39.170), живое основание гейта — `PD-422` · **(6) разморозка фронта** — ПОСЛЕ (4): зеркало отстало на СЕМЬ миноров (`frontend/docs/api-contract/openapi.yaml` — `0.2.3` против канона `0.9.0`, и первый из них — ЛОМАЮЩИЙ 0.3.0), 16 операций против 20; отставание ратифицировано D39.142 п.5 на время фриза и две ручки разъехались, размораживать раньше значит перегенерировать типы дважды. ⚠ **ДВА ЗАГЕЙЧЕННЫХ ТРИГГЕРА НАЖАТЫ И НЕ ОТРАБОТАНЫ — строка бэклога 237** (`go.work` · вендор-сверка эффорта `deepseek-v4-pro`; реестр `13-tech-debt-anchors.md` §Б-108). ⚠ **Состояние git — снимать КОМАНДАМИ, не чтением** (ветка `polygon` ушла вперёд, коммит здесь не цитирую): работа полигона лежит на ней и в `main` НЕ влита, а `git status -- eval/` в main-дереве пуст ПО ПОСТРОЕНИЮ и уводит в ложный вывод «работы нет»; `origin/main` остаётся ПРЕДКОМ `main` (`git merge-base --is-ancestor origin/main main`). +> **⟶ ТЕКУЩЕЕ СОСТОЯНИЕ** (на 2026-09-01, голова D39.185 — КУРС: движок и платформа до «работает и отдаёт результат», фронт ЗАМОРОЖЕН и P7 его НЕ размораживает (D39.147). **ОЧЕРЕДЬ №22** (единственный носитель — здесь; роль передана 01.09, №21 закрыт нотой передачи D39.184). ⚠ **ЗАКАЗ ВЛАДЕЛЬЦА 01.09 — ПЕРВЫМ:** (0а) **ревизия документации на ПРОТУХШЕЕ** — по всем зонам, не только тронутым; (0б) **планы доработок в БЭКЕНД и ПЛАТФОРМУ** по остатку бэклога и регистра; (0в) **вынос неактуального в АРХИВ** (`docs/archive/`, `platform/docs/archive/`) — за сутки 31.08 закрыто много, и часть носителей стала историей. ⚠ Трезвость по масштабу (пере-считано 02.09): **88** живых доков в `docs/` против **198** заархивированных, 8 в `platform/docs`, 9 в `backend/docs` — ⚠ из 88 три ВРЕМЕННЫЕ (`DOC_CLEANUP_PLAN` · `DOC_REVISION_FINDINGS` · `DOC_REVISION_REFUTED`), они уедут в архив по закрытии разбора, то есть постоянных **85**; счёт бэклога — бюллетенем ниже, открытых рядов регистра платформы — 97 (major 2) ⚠ (ревизией 02.09 ряды **154** и **157** переведены из «скоро» в «когда-нибудь»: их гейтом стоял первый холодный прогон, он ОТРАБОТАЛ 31.08 и оба предусловия оказались другими — разбор в самих ячейках, ни одна НЕ закрыта). ⚠ Числа доков `counts.py` НЕ сторожит — при переносе файлов пере-считывать руками командой `find docs -name '*.md' -not -path 'docs/archive/*' | wc -l`. ⚠ И предупреждение о МЕТОДЕ, купленное сменой №21: «выглядит протухшим» ≠ «протухло». Три факта оркестратора опровергнуты ЗАМЕРОМ сессий, а якоря `15-money-path.md` в девяти случаях из двенадцати РОДИЛИСЬ верными и сгнили дрейфом — то есть ревизия обязана быть исполнением, а не чтением. ⚠ **ОЧЕРЕДЬ, унаследованная от №21** (⚠ **пак P12 ПРИНЯТ И ЗАЛЕНДЖЕН 31.08 — D39.180**, вместе с контрактным минором **0.9.0**; `PD-425` закрыт им же. ⚠ **ДВА ЛЕНДИНГА 31.08:** бэкенд-пак **«ДЕНЬГИ И ЧЕСТНОСТЬ ВЫДАЧИ» — D39.182** (счёт линз, блокеров и урок «дефект в самом лекарстве» — телом ноты; тестов 1045→1083, удалённых ноль) и ратифицированный владельцем **ЗАКОН РАСКРЫТИЯ движка — D39.181**, применённый к одиннадцати экземплярам): **(1) РАЗРЫВ ЦИКЛА: книга не отдаётся файлом ПОЛЬЗОВАТЕЛЮ — открыта ПЛАТФОРМЕННАЯ половина.** Движок пишет файл с 30.08 (`tmctl build` — EPUB 3 + чистый txt, D39.175), и холодный прогон 31.08 предъявил это живьём: собранный EPUB настоящего перевода прошёл `epubcheck` 0/0/0/0 и передан владельцу. Открыто ровно одно: канон обещает `createExport`/`getExport`, а платформа их НЕ монтирует (смонтировано 15 операций из 20; нет также `getRun`, `updateBook`, `deleteBook`). Долг числится с P8 (`platform/BACKLOG.md` П-17), и НИ ОДИН пак платформы после P7 его не взял (проверка вместо ручного счёта, чтобы не гнило при каждом лендинге: `grep -rn 'createExport\|getExport' platform/internal/ --include=*.go` — пусто). **Слово «отдаёт результат» ложно по букве ТОЛЬКО платформенной половиной** (п.4) · **(2) ~~холодный прогон движка~~ ОТРАБОТАЛ 31.08, закрыт РЕШЕНИЕМ ВЛАДЕЛЬЦА «не доводить»** (отчёт — `archive/reports/COLDRUN_V16_REPORT_2026-08-31.md`, числа относятся к `065d8ac`). Потрачено **$0.436110** из санкции $0.80. ПРЕДЪЯВЛЕНО живьём: объёмный потолок · D39.158 ОБЕИМИ половинами (стоп и не-стоп) · exit 16 · строки 154/198/239/240. ⚠ **Причина большой доли редактора НЕ УСТАНОВЛЕНА** — три каузальные истории построены и две сняты. Доля редактора идёт с ДВУМЯ знаменателями: **49.3%** от всего прогона ($0.214865 из $0.436110) и **81.3%** внутри порции П1 (⚠ ходившее «73%» — фантом, в отчёте его нет ни разу). Следующий шаг — контролируемая проба по ЧЕТЫРЁМ осям (§14 отчёта): трудность чанка БЛОКИРОВАТЬ, длину входа КОНТРОЛИРОВАТЬ, промпт по SHA, эффорт `off` против `low`. Ось `stale` НЕДОСТИЖИМА (под дрейфом `staleUnits` возвращает UNKNOWN немедленно). ⚠ **Цена: слово владельца 31.08 — ≈$0.60, потолок $0.80, ДЕСЯТЬ глав ПОЛНОЙ цепью включая редакторскую волну.** ⚠ **ГЕЙТ КЛЮЧЕЙ СНЯТ словом владельца 30.08** (D39.176 п.6), но конвенционного `.env` НЕТ НИ У ОДНОЙ книги корпуса — прогон обязан передавать `--keys-file` абсолютным путём; заполнены только `projects/textmachine/backend/.env` и `.../eval/.env`. ⚠ Для п.3 нужен ДРУГОЙ файл — путь платформы `TM_PLATFORM_ENGINE_KEYS_PATH`. **Вопрос владельцу СНЯТ 31.08 вычитанием инженерной половины:** формат обоих файлов совпадает (`KEY=VALUE`), переменная требует АБСОЛЮТНОГО пути (`platform/internal/config/config.go`, греп `must be an absolute path`), едет `--keys-file` и только на `translate`; заполненный файл на машине существует. Лечение операционное и $0 — направить переменную на него; проверять ПРОГОНОМ, не чтением (гардрейл `.env`) · **(3) живой сквозной прогон через API платформы** — форма манифеста, сайдкара банка и карта причин флагов сочинены платформой САМОСТОЯТЕЛЬНО. ⚠ Уточнено 01.09: гейт СНЯТ холодным прогоном, и настоящие артефакты движка теперь ЕСТЬ (каталог `books/gu-zhenren/coldrun-v16/`), но сверка вышла ТОНКОЙ: на шов реально вышло **одно значение `flag_reason` из пятнадцати** (`sanitizer_stripped`), остальные четырнадцать по-прежнему только чтением кода, а манифест против `platform/internal/ingest/manifest.go` не сверялся вовсе · **(4) дверь выдачи** — строго ПОСЛЕ (3) (⚠ слово владельца 30.08: дверь ВСЕГДА строит файл — отказ юзеру не отдаётся, неполная книга уходит с пометкой, т.е. дверь зовёт `tmctl build --partial`; отказ по умолчанию остаётся операторской ручкой CLI; D29.1(б) «fail-closed» читать как «никогда молча» — честность несут пометки) · **(5) проводка `--max-units`** — снятие гейта, а не стройка: механизм в движке стоит (D39.170), живое основание гейта — `PD-422` · **(6) разморозка фронта** — ПОСЛЕ (4): зеркало отстало на СЕМЬ миноров (`frontend/docs/api-contract/openapi.yaml` — `0.2.3` против канона `0.9.0`, и первый из них — ЛОМАЮЩИЙ 0.3.0), 16 операций против 20; отставание ратифицировано D39.142 п.5 на время фриза и две ручки разъехались, размораживать раньше значит перегенерировать типы дважды. ⚠ **ДВА ЗАГЕЙЧЕННЫХ ТРИГГЕРА НАЖАТЫ И НЕ ОТРАБОТАНЫ — строка бэклога 237** (`go.work` · вендор-сверка эффорта `deepseek-v4-pro`; реестр `13-tech-debt-anchors.md` §Б-108). ⚠ **Состояние git — снимать КОМАНДАМИ, не чтением** (ветка `polygon` ушла вперёд, коммит здесь не цитирую): работа полигона лежит на ней и в `main` НЕ влита, а `git status -- eval/` в main-дереве пуст ПО ПОСТРОЕНИЮ и уводит в ложный вывод «работы нет»; **«развязка git с origin» ОПРОВЕРГНУТА** — `origin/main` остаётся ПРЕДКОМ `main`, расхождения нет (`git merge-base --is-ancestor origin/main main` → rc 0). ⚠ Пункт «развязка git с origin» в листе владельца ниже держится ТОЛЬКО как вопрос про force-push его рукой; утверждением о расхождении дерева он не является — арбитр этой пары именно здесь. > - ⚠ **Норма приёмки, купленная аудитом D39.167 п.1:** акт лендинга, объявивший закрытие строки регистра или бэклога, обязан быть СВЕРЕН СТАТУСОМ в тот же заход — иначе следующий пак собирается ПО РЕГИСТРУ и едет чинить построенное. Машинная половина — строка бэклога **225**. > - ⚠ **ЛЕНТА КОНТРАКТНЫХ МИНОРОВ** (что принёс каждый — телом ноты): **0.5.0** — D39.161 · **0.6.0** — D39.162/D39.163 · **0.7.0** — D39.166 · **0.8.0** — D39.169 · **0.9.0** — D39.180. Прожитые дампы приёмок P9/P10 — `archive/PROGRESS-2026-08-backend.md` и тела нот. > - **Эра №15 закрыта — семь приёмок, все ПРИНЯТЫ и залендены**; лента, коммиты и разборы — D39.109–123 (D-лог) и реестр нот `architecture/05-decisions-index.md`; снимок прежних бюллетеней этой шапки — архив-слайс `-08-02-04`. @@ -148,7 +148,7 @@ | 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)| оркестратор | скоро (остаток = только (б) зеркало фронта при разморозке) | P7 → фронт при разморозке | D39.138, D39.142, **D39.143** | | 184 | **Жанр книги — ВЫКИНУТЬ (слово владельца 16.08). ⚠ ДВЕ ПОЛОВИНЫ ИЗ ЧЕТЫРЁХ УЖЕ ИСПОЛНЕНЫ** (сверено кодом при аудите доков 22.08): поле ушло из контракта и из формы интейка батчем 0.3.0, и платформа жанра больше НЕ ЗНАЕТ — `platform/internal/books/render.go` несёт `genre` шаблона нечитаемым насквозь и говорит об этом прямо. **ЖИВЫМИ остаются две:** (а) движковая — снять `{{genre}}` из промптов пары (⚠ испр. 30.08: он в ШЕСТИ промптах пары, а не в трёх; состав здесь НЕ держим — снимать командой `grep -rln "{{genre}}" backend/prompts/`) + поле из канона брифа: двигает `BriefHash` ⇒ ТОЛЬКО в общее resnapshot-окно, координировать со 161/182, дешёвое окно пока платная книга одна; (б) фронтовая — форма при разморозке; влияние жанр-строки на качество не измерено и уже не будет | бэкенд (+платформа/контракт/фронт) | скоро (движковая половина — resnapshot-окном) | касание в окне 161/182 + батч 183 | research/28 Б-23/§8 п.6, D39.138 п.2в | | 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_DIRECTION.md:202-205`), семантика — в спеку батчем 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д | +| 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`, греп `Условные запросы` — ⚠ прежний голый якорь `:202-205` съехал, там сегодня про склейку `note`), семантика — в спеку батчем 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 | @@ -179,7 +179,7 @@ | 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'ом вендора, а носители до сих пор ПРОТИВОРЕЧАТ (квирк-канон и `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:504`=`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)** — и был вдвое больше заявленного: не 13 якорей, а **51** (34 уехали, 1 мёртв, 16 верны), а дороже адресов оказались ЛОЖНЫЕ КЛЕЙМЫ (цитата контракта, которой нет; потерянный третий член `Usage`; живой К-13 при закрытом D39.132; метод `Settle`, которого нет). Чинилась ФОРМА, не номера: сверяемых гейтом по содержимому стало 89→127 · **arch-5** (правило языка знает две корзины, `reader.txt` — третья) · **arch-7** (§2 закона шва: дисциплина флока не описывает новый глагол-писатель) · **arch-9** (реестр загейченных триггеров не знает нажатых 30.08) · **arch-10** (`16-events-emitter.md`: словарь и `StreamVersion` разошлись с кодом обеих зон) · **arch-11** (`10-prompt-architecture.md`: описывает несуществующий с пака-15 ключ `prompts:`) · **arch-12** (шапка `09-target` сама зовёт себя неполной — строку под таблицей слоёв надо внести) · **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 часа) | оркестратор | скоро | пройти списком; major (arch-3) первым — док про деньги врёт указателями | аудит доков 30–31.08, сдача смены №20 | +| 243 | **Остаток аудита доков 30–31.08: 19 удержанных находок НЕ применены** (аудит — 5 линз + верификатор на каждую, 57 находок, 55 удержаны, 36 применены сменой №20). Перечень: ~~**arch-3**~~ **ЗАКРЫТ 31.08 (D39.179 п.5)** — и был вдвое больше заявленного: не 13 якорей, а **51** (34 уехали, 1 мёртв, 16 верны), а дороже адресов оказались ЛОЖНЫЕ КЛЕЙМЫ (цитата контракта, которой нет; потерянный третий член `Usage`; живой К-13 при закрытом D39.132; метод `Settle`, которого нет). Чинилась ФОРМА, не номера: сверяемых гейтом по содержимому стало 89→127 · **arch-5** (правило языка знает две корзины, `reader.txt` — третья) · **arch-7** (§2 закона шва: дисциплина флока не описывает новый глагол-писатель) · **arch-9** (реестр загейченных триггеров не знает нажатых 30.08) · ~~**arch-10**~~ **ЗАКРЫТ 02.09** — числа словаря из тела дока сняты, носитель назван кодом (`docs/architecture/16-events-emitter.md`, греп `Словарь событий — В КОДЕ, не здесь` → `backend/internal/runevents/runevents.go`, греп `const StreamVersion`) · ~~**arch-11**~~ **ЗАКРЫТ 02.09** — ключ назван ОТВЕРГНУТЫМ, а не действующим (`docs/architecture/10-prompt-architecture.md`, греп `ОТВЕРГАЕТСЯ загрузкой`) · **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 часа) | оркестратор | скоро | пройти списком; major (arch-3) первым — док про деньги врёт указателями | аудит доков 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 | | 246 | ⚠ **ДВЕ КОПИИ ПОЛОСЫ ОТКАЗОВ 10–19 ОБЕЩАЮТ РАЗНОЕ — потребитель держит гарантию, которую производитель ОТОЗВАЛ.** Движок (`backend/cmd/tmctl/main.go:53`=`Nothing was written` is NOT the band's promise any more): «„Nothing was written“ is NOT the band's promise any more … **exit 15 legitimately answers with files on disk**». Платформа (`platform/internal/ingest/exit.go:38`=`nothing this process would have written was written`): «… and nothing this process would have written was written». ⚠ Опасность не теоретическая: по `PD-196` интейк действует по полосе РАЗРУШИТЕЛЬНО (отклоняет книгу и удаляет загрузку), а `exit 15` теперь легитимно оставляет файлы на диске. Хвост: движковый `exitBookIncomplete = 16` у платформы константы НЕ имеет вовсе (её словарь 10·11·12·13·14·15·19). ⚠ **Денежная половина ЦЕЛА в обеих копиях** (`nothing was spent` — по одному хиту в каждой), поэтому запрет отказывать классом полосы там, где деньги уже потрачены, в силе. Предсказано п.6 закона шва 17 | платформа (правка) + оркестратор (маршрут) | СРОЧНО | зона платформы приводит свою копию к движковой ЛИБО обе стороны идут в ратификацию, если расхождение намеренное | пак «деньги и честность», находка A15 вне заказа, 31.08; пере-проверено оркестратором дословно обеими копиями | @@ -187,7 +187,7 @@ | 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 | **Колонка веса бэклога не судится ничем, и девять рядов её потеряли.** Правило таблицы (легенда ниже) даёт ТРИ веса — «блокер-очереди» · «скоро» · «когда-нибудь», — но `counts.py` словаря весов бэклога НЕ ИМЕЕТ: `WEIGHT_VOCAB` в нём — словарь РЕГИСТРА платформы (`major/minor/info`), а `backlog()` лишь считает подстроку «скоро». Замер 02.09 самопроверочным скриптом (`cells(l)[-4]` по всем рядам): **девять** ячеек веса не содержат ни одного слова словаря — ряды **5 · 13б · 94 · 96 · 97 · 149 · 205 · 221 · 246** («отложено-до-замера», «СРОЧНО», «—», «сделано 21.08», «гейчена разморозкой фронта»…). Три из них — 96/97 — надгробия переехавших в зонный бэклог строк, у них «—» законно; остальные шесть потеряли вес молча. ⚠ Найдено не ревизией, а ПОБОЧНО: контролёр приёмки заметил, что мои же две правки снесли вес-слово, я починил свои и пере-считал весь трекер. ⚠ **ВТОРАЯ ПОЛОВИНА КЛАССА, найдена тем же заходом: у ячейки веса нет ни словаря, ни ЭКРАНИРОВАНИЯ.** Счётчик ищет подстроку ГДЕ УГОДНО в ячейке, поэтому упоминание веса в прозе неотличимо от самого веса: фраза «переведена из «скоро»» ре-добавила два ряда в счёт (53 → 56 при одной новой строке), поймано пере-счётом скриптом. **Лечение ОДНИМ правилом на обе половины: вес обязан быть ПРЕФИКСОМ ячейки** (`startswith` по трём словам), и «скоро» считается тоже по префиксу, а не подстрокой — тогда потеря веса и ре-добавление счётом умирают одной проверкой, без экранирования. Сегодня такой гейт даёт **9 нарушений, а не 0** — он родится КРАСНЫМ, и это правильно: покажет то, что есть. ⚠ Два ряда девятки шире класса: **149** («исполнен и заленден 10.08») и **205** («сделано 21.08») объявляют себя ИСПОЛНЕННЫМИ прямо в колонке веса, хотя по правилу таблицы закрытые строки в ней не живут — это либо живой остаток без веса, либо непойманный класс C; **246** несёт самодельное «СРОЧНО», которого в словаре нет. **Решение владельца нужно только на форму гейта; сами девять ячеек чинит оркестратор.** | оркестратор | скоро ($0, гигиена трекера) | режим `counts.py` + правка девяти ячеек | ревизия доков 02.09, приёмка контролёра | | 217 | **Скрипты полигона захардкодили АБСОЛЮТНЫЕ пути двух корней и не работают на этой машине вовсе.** ДВА РАЗНЫХ слома. **Корень репо** — смена пользователя: литерал в 121 файле, из них 104 дословно `REPO = Path("/home/ubuntu/projects/textmachine")`, портабельных форм всего 5. **Корень книг** — оба события порознь: литерал `/home/ubuntu/books` 86 файлов (пользователь), портабельный `Path.home()/"books"` 89 файлов (переезд каталога; на прежних машинах работал). Объединение 173 файла. Пользователь теперь `ubuntu-26`, книги переехали в `<репозиторий>/books` ⇒ ломается и то и другое, включая ЖИВОЙ гейт фазы Д `eval/conformance.py:48`=`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: три эрраты за сессию убили якоря в `17-seam-inbound-law.md:120` и `research/25-seam-cold-review.md:5` (оба целили в `:232`, тело уехало на `:239`). Лечение — не пере-нацеливание (оно повторится через эррату), а СМЕНА ФОРМЫ якоря: в тела D-лога целиться номером ноты (`^## D39.106`), который стабилен навсегда, а не строкой. ⚠ Строка ОБЪЯВЛЕНА в CURRENT-STATE 24.08 и до 27.08 в таблице НЕ СУЩЕСТВОВАЛА — очередь три дня ссылалась на носитель, которого нет; поймано свипом якорей при выдаче контрактного минора (⚠ D39.157 п.6 объявил класс закрытым 24.08 — носителя в таблице тогда не было). ⚠ **Первая половина лекарства ПОСТРОЕНА:** `counts.py --lint` сверяет якоря в тела D-лога СТРУКТУРНО и без токена — владелец целевой строки (ближайший `^## D<номер>`) обязан совпасть с номером, названным рядом; остаётся перевести живые якоря на форму номера | оркестратор | скоро (растёт с каждой эрратой) | `--lint` учит форму `файл:^## D<номер>`, живые якоря в D-лог переводятся на неё | ревью доков 24.08, механизм и отсутствие носителя — 27.08, D39.160 | +| 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`), который стабилен навсегда, а не строкой. ⚠ Строка ОБЪЯВЛЕНА в CURRENT-STATE 24.08 и до 27.08 в таблице НЕ СУЩЕСТВОВАЛА — очередь три дня ссылалась на носитель, которого нет; поймано свипом якорей при выдаче контрактного минора (⚠ D39.157 п.6 объявил класс закрытым 24.08 — носителя в таблице тогда не было). ⚠ **Первая половина лекарства ПОСТРОЕНА:** `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:500`=`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 | @@ -270,8 +270,9 @@ > файлами зоны: `backend/docs/MONEY_HONESTY_REPORT.md` (§7 — пинги оркестратору, §9 — десять экземпляров > закона по одному, §0.1 — батарея ИСПОЛНЕНИЕМ, **§5.1 — разложение покупок П1/П2/П3**: ось пере-покупки > терминолога = БАЙТЫ БАТЧА, а не сдвиг снапшота — это и есть «пинг №2», которым D39.185 п.1 адресует сюда; -> ⚠ §6.2 «адверсариальный проход» и дифф `^func Test` в отчёте БОЛЬШЕ НЕ ЖИВУТ — сняты ревизией доков 02.09, -> и счёт тестов 1045→1083 при нуле удалённых держит теперь только шапка CURRENT-STATE), +> ⚠ испр. 02.09: **§6.2 «адверсариальный проход» в отчёте ЖИВ** — `backend/docs/MONEY_HONESTY_REPORT.md`, греп +> `^## 6.2`; ревизией доков 02.09 снят только дифф `^func Test`, и счёт тестов 1045→1083 при нуле удалённых +> держат теперь шапка CURRENT-STATE и тело **D39.182**), > `backend/docs/DISCLOSURE_LAW_DESIGN.md`, `backend/docs/MONEY_HONESTY_PLAN-NOTE.md`; промт — > `archive/prompts/BACKEND_MONEY_HONESTY_SESSION_PROMPT.md`. **Живой остаток пака — строками бэклога:** > **246** (две копии полосы отказов 10–19 обещают РАЗНОЕ, СРОЧНО) · **247** (§2.2 закона опровергает себя) · @@ -320,15 +321,19 @@ в файле. Живым из неё остаётся только ⚠0731 (смена весов под слагом) и стохастичность эха. 2. **`eval/README.md` описывает каталог `dovodka/` ОДНИМ файлом `runs.py`**, тогда как там сорок скриптов и главный инструмент фазы; `docs/experiments/README.md` объявляет себя сведённой «до эксп-22», а строк для 22 и 23 в ней нет. -3. **`naklon.py` (гейт позиционного наклона) в git ОТСУТСТВУЕТ** (`git ls-files eval/dovodka/naklon.py` — пусто при - 42 отслеженных файлах каталога) ⇒ из чистого клона эта часть фазы не воспроизводится. ⚠ Прежний дамп состояния +3. **`naklon.py` (гейт позиционного наклона) лежит коммитами ветки `polygon`, в `main` НЕ влит.** ⚠ Испр. 02.09: + прежняя редакция пункта утверждала «в git ОТСУТСТВУЕТ ⇒ из чистого клона эта часть фазы не воспроизводится» — + **обе половины ЛОЖНЫ.** Файл несут и локальная `polygon`, и запушенная `origin/polygon` (проверка: + `git ls-tree origin/polygon -- eval/dovodka/naklon.py` — один блоб; `git ls-tree main -- eval/dovodka/naklon.py` + пусто — из этой-то пустоты, снятой в main-дереве, и родился ложный вывод «вне git»). Живой остаток — не «вне git», а НЕ ВЛИТО в `main`: + в `eval/dovodka/` у `main` 42 отслеженных файла против 80 у `polygon`. ⚠ Прежний дамп состояния дерева (13 изменённых + 6 неотслеженных файлов, 22.08) СНЯТ 02.09 как прожитый: `git status -- eval/` в main-дереве пуст, работа зоны лежит коммитами на ветке `polygon`. **ФАЗА Д «ДОВОДКА ЭКСП-22/23» — ИДЁТ.** ⚠ **Живое состояние фазы живёт В ЗОНЕ, не здесь** (`eval/dovodka/` — планы, консилиум, ревью; свежий носитель курса зона называет сама), приёмка фазы — у ПАРАЛЛЕЛЬНОГО оркестратора, деньги и цепь потолков — `eval/dovodka/money_d.py` (`PACK_CEILING`/`CEILINGS`), а не литералом здесь: три поколения записей в одном месте и были причиной, по которой состояние фазы стало нечитаемым. *(Хроника фазы Д — записи 10.08 (сессия №1) и 15.08 (сессия №2, сквозной аудит дуги 19→23 и пере-судейство `tier`) — вынесена в [archive/PROGRESS-2026-08-10-15.md](archive/PROGRESS-2026-08-10-15.md) с тремя поправками в шапке: потолок, закрытые пункты листа владельца, протухшие «долги». Открытым на владельце из неё остаётся ОДИН пункт — возражение Sol по проходу `tier`.)* -**Диспозиция оркестратора №17 (15.08), живая до приёмки фазы Д:** просьба хендоффа «эррата zh-канона: пере-сборка = правка закрытой оси, ратифицирует оркестратор» (`POLYGON_PHASE_D_HANDOFF.md:84-86`, завышение +0.0039, вердикты не двигает) — **к ПАРАЛЛЕЛЬНОМУ оркестратору при приёмке, не к движковому** (приёмка фазы Д — его зона). Прожитое из записи (вторая передача и мелочи аудита корпуса) — `archive/reports/CORPUS_AUDIT_2026-08-15.md`; санкции владельца по деньгам фазы и замене ja-книги — D39.136 п.1. +**Диспозиция оркестратора №17 (15.08), живая до приёмки фазы Д:** просьба хендоффа «эррата zh-канона: пере-сборка = правка закрытой оси, ратифицирует оркестратор» (`docs/POLYGON_PHASE_D_HANDOFF.md:85`=`Пере-сборка = правка закрытой оси`, завышение +0.0039, вердикты не двигает) — **к ПАРАЛЛЕЛЬНОМУ оркестратору при приёмке, не к движковому** (приёмка фазы Д — его зона, №17 полигон не трогает **по слову владельца**). Прожитое из записи (вторая передача и мелочи аудита корпуса) — `archive/reports/CORPUS_AUDIT_2026-08-15.md`; санкции владельца по деньгам фазы и замене ja-книги — D39.136 п.1. *(Память · Голос и состояние · Ридер-IDE — ЗАКРЫТЫЕ секции (D39.125): темы исполнены/переехали в зонные журналы; хроника — в архив-слайсах. Фронт пишет ТОЛЬКО в frontend-PROGRESS.md.)* diff --git a/docs/architecture/02-mvp-plan.md b/docs/architecture/02-mvp-plan.md index 9fa94906..16a94b45 100644 --- a/docs/architecture/02-mvp-plan.md +++ b/docs/architecture/02-mvp-plan.md @@ -48,7 +48,7 @@ - Чувствительный контент: **механизм построен паком-17** (content-labels × `accepts_labels`, D39.25/D39.26–D39.28) — чанк-классификатор 0–3 и «каналы A/B» упразднены. Остаётся в Ф2: детектор молчаливых вырезаний, refusal-мониторинг. - Интеграция llama-server (скрининг, abliterated канала B, эмбеддинги bge-m3 — второй эшелон, low-trust A7). - Python-сайдкар качества: CometKiwi (валидировать на ru-литературе до доверия) + **морфо-гейт рода** (жалоба №1 читателей; pymorphy, вкл. глагол прош. вр. — C3 реестра) + гейт ты/вы по series-bible-lite + канцелярит-чеклист Галь; кандидат: T-index как офлайн-метрика translationese (готовое решение, 0.5B — влезает в стенд). -- **B6: валидатор Палладия/Поливанова** — ПОСТРОЕН generic-парсером + langpack-таблицами (D39.16, `internal/lang` + `configs/langpacks/zh-ru/palladius*.txt`); таблицы Поливанова = данные ja-пары, которых в репо ещё нет (ruby-reading — их ground-truth). +- **B6: валидатор Палладия/Поливанова — ПОСТРОЕНА ТОЛЬКО ПАЛЛАДИЙ-ПОЛОВИНА** (⚠ испр. 02.09): generic-парсер таблиц + сами таблицы-данные — `backend/internal/lang/langpack.go`, греп `pairFiles = []string{"palladius.txt"` + `backend/configs/langpacks/<пара>/palladius*.txt`; алгоритм слого-сегментации — `backend/internal/miner/miner_palladius.go`, греп `buildPalladiusCyrSyllables` (D39.16). **Поливанов-валидатора в коде НЕТ**: таблицы Поливанова = данные ja-пары, которых в репо нет (ruby-reading — их ground-truth); улика и грепы — `docs/architecture/13-tech-debt-anchors.md`, срез строки 81, греп `Поливанов-валидатор`. - Резюме глава→арка→книга + гейт фактичности резюме (D1 реестра — у резюме нет post-check-аналога). Ты/вы-журнал ПОСТРОЕН — `address_pairs` (D7-Amendment-1/D21 п.2), `speech` deprecated D39.55. - Batch API (−50% только Gemini-судье/QA — exp08), нативный Gemini-адаптер (safety-контроль судьи, rf-замер), стриминг keep-alive. - Eval-харнесс (golden-set реплей, свип порогов); регрессионный сьют из чек-листа «особо опасных ошибок» (12-common-failures §16: отрицание, перепутанный субъект, внутренняя речь→прямая). diff --git a/docs/architecture/03-implementation-notes.md b/docs/architecture/03-implementation-notes.md index 13edcda2..36907aa7 100644 --- a/docs/architecture/03-implementation-notes.md +++ b/docs/architecture/03-implementation-notes.md @@ -7,6 +7,8 @@ Вердикт шага 0 — перевалидации решений v2 глазами реализатора перед Фазой 0 (метод: построчное чтение донорского кода vojo + четыре критик-линзы, ~940k токенов; донорский отчёт — `../research/10-vojo-ai-bot-review.md`). **Живое здесь — §3: контракты, которые Фаза 0 приняла на себя.** Разделы «общий вердикт исполнимости» и «упущения передавшей сессии» СНЯТЫ как прожитые: их предмет либо стал контрактом §3 (cache-write в `Usage` и формула стоимости — §3.5 · таймауты/ретраи параметрами клиента и чтение `Retry-After` вместо трёх захардкоженных · мини-раннер C1), либо ушёл в свои дома — прокси-ловушка (Go stdlib не проксирует loopback, опасны не-loopback локальные адреса вроде WSL-gateway 172.x; в коде `llm.NoProxyClient`) и мёртвый Grok 4.1 Fast живут в `docs/experiments/00-provider-quirks.md` и `backend/configs/models.yaml`, оценка переписывания `store.go` и счётчики донора — в `../research/10-vojo-ai-bot-review.md`, хроника — `../archive/PROGRESS-2026-07-04-10.md`. +> ⚠ **§2 СНЯТ — а код на него ещё ссылается, поэтому вот куда он уехал** (заглушка, испр. 02.09): **п. 2 (таймауты/ретраи параметрами клиента, чтение `Retry-After` вместо трёх захардкоженных)** → параметры клиента в `backend/internal/llm/httpllm.go`, греп `03-implementation-notes §2 item 2`; **п. 5 (single-connection write pool + `BEGIN IMMEDIATE`)** → §3.6 «SQLite-рецепт» ниже, носитель кода — `backend/internal/store/store.go`, греп `03-implementation-notes §2 item 5`. Комментарии в коде НЕ трогались — их адресат теперь описан здесь. + ## 3. Контракты Фазы 0 (обязательства реализации) ### 3.1 Детерминизм и request-hash (Р6) diff --git a/docs/architecture/05-decisions-log.md b/docs/architecture/05-decisions-log.md index 20d716cd..de31161b 100644 --- a/docs/architecture/05-decisions-log.md +++ b/docs/architecture/05-decisions-log.md @@ -38,6 +38,9 @@ > (`sqlgate_test.go`, `172 statements`); моё 167 получено грепом и унаследовано в тело ноты. Пол 140 > далёк в обоих случаях, вывод приёмки не меняется, но в каноне стоит число из гейта, а не из грепа. +> ⚠ **Эррата 02.09-а (D39.182, «три блокера приёмки закрыты») — у ТРЕТЬЕГО блокера не осталось носителя.** Заголовок и §1 ноты держат счёт «3 блокера», но отчёт пака называет сегодня только два: ревизия доков 02.09 сняла из `backend/docs/MONEY_HONESTY_REPORT.md` разделы «Сверка с заказом по пунктам» и «ПРИЁМКА: три блокера и пять дофиксов» (проверка: греп `^## 9.11` и `^## 1\.` по файлу — пусто, при живом `^## 6.2`). **Третий блокер — вердикт «предъявлено» поверх неработающего пути:** в снятом §1 отчёта вердикты **A0** и **A6** стояли «предъявлено» на НЕПОЛНОЙ проверке и были сняты вместе с блокером 2, а пере-предъявлены посадками `TestAHealthyGlossaryPassIsNotReportedAsALoss` и `TestTheCONSENTGateSeesAnInPlaceSourceEdit` (грепаются по `backend/`). Дословный текст снятых разделов — `git show bd2077b:backend/docs/MONEY_HONESTY_REPORT.md`. Тело ноты не переписывается (D23.3). +> ⚠ **Эррата 02.09-б (форма якорей в ТЕЛАХ этого файла) — правке не подлежит, читать с поправкой.** Дисциплина D23.3 запрещает переписывать тела, поэтому четыре голых `файл:строка` внутри нот остаются как есть, и часть из них уже съехала: в теле **D39.134** (греп `deploy/README.md:131` — цель ЖИВА, строка `pipeline:` рецепта) · в теле **D39.153** (греп `docs/STACK.md:11` — цель ЖИВА, строка редактора `deepseek-v4-pro`) · в теле **D39.165** (греп `17-seam-inbound-law.md:102` — цель УЕХАЛА, там пустая строка; живой адрес будущих дверей — `docs/architecture/17-seam-inbound-law.md`, греп `| дверь | откуда следует |`) · в теле **D39.168** (греп `17-seam-inbound-law.md:62-64` — цель ЖИВА, закон шва п.3, но названный рядом `backend/internal/pipeline/status.go:148-149` УЕХАЛ на `:155-156`=`const statusVersion`). Правило разбора для всех новых записей: якорь — `путь:строка=подстрока` либо греп, голых `file:line` не вписывать (строка бэклога 219). + > ⚠ **Навигация (актуализация 07.08, эра D39.1xx):** append-only-дисциплина (D23.3) означает, что > НЕВЕРНЫЙ ФАКТ внутри старой ноты не переписывается, а получает эрратау — и тогда он опасен ровно > тем, что грепающий его найдёт ПЕРВЫМ, а эрратау ниже может не дочитать. Поэтому поправки к фактам diff --git a/docs/architecture/06-memory-risk-registry.md b/docs/architecture/06-memory-risk-registry.md index c52d70ff..e1d989bd 100644 --- a/docs/architecture/06-memory-risk-registry.md +++ b/docs/architecture/06-memory-risk-registry.md @@ -102,7 +102,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`, Палладий/Поливанов B6 — `internal/lang` + `configs/langpacks/<пара>/palladius*.txt` (D39.16). Бэкап/интеграл файла книги (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` (хвост — в бэклоге `../PROGRESS.md`). Из отложенного НЕ построено (греп по `backend/` — 0 хитов): гейт фактичности резюме (D1 — резюме нет вовсе), whole-book эмбеддинг-слой (A7/D2 — горячий путь по-прежнему «no embeddings»), морфо-гейт глагольного рода (C3, Ф2). ### Ruby-seed контракт (форма подтверждена оркестратором 05.07) diff --git a/docs/architecture/10-prompt-architecture.md b/docs/architecture/10-prompt-architecture.md index ebedf918..173494aa 100644 --- a/docs/architecture/10-prompt-architecture.md +++ b/docs/architecture/10-prompt-architecture.md @@ -2,7 +2,7 @@ > **⚠ СТАТУС: несущая часть ПОСТРОЕНА.** Pair-keyed промпты резолвятся КОНВЕНЦИЕЙ пути `prompts/<пара>/<роль>.md` + конфиг-слой пары `configs/pairs/` (пак-15, D39.23), repair-промпты — `prompts/<пара>/repair/<класс>.md` (пак-16, D39.24). Паком-20 добавились роль `terminologist` (пар-пак, интерим-текст) и вариантный `translator-banknote.md`; редакторская инъекция стала двухсекционной (D39.45), а жанровый словарь ОТМЕНЁН как класс (D39.47). ⚠ **Ждёт внесения:** D39.104 — инъекция схлопывается в ЕДИНЫЙ закон-блок, маркер ⟨проверить⟩ снимается с провода, право «перевести иначе» упраздняется; внесение = строка 134 ПОСЛЕ пробы 18. > -> «Структурированный пакет конвенций пары» (§3) остаётся дальним планом. Док — одно место по теме промптинга и реестр открытого; **при конфликте побеждает D-лог**, обновлять при каждом лендинге, трогающем промты или слой 2. +> «Структурированный пакет конвенций пары» (§3) остаётся дальним планом. **Заметка собрана оркестратором 2026-07-16 по запросу владельца** («где заметка про промтинг?») — до неё тема концерна 4 арх-ресета была размазана по `08-sync-audit-ledger` (дорожка L4), `09-target-architecture` (§0.1, §2 слой 2), D-логу (D30.2, D39 п.7, D39.1–39.2) и research/18–19. Док — одно место по теме промптинга и реестр открытого; **при конфликте побеждает D-лог**, обновлять при каждом лендинге, трогающем промты или слой 2. ## 1. Четыре вопроса владельца → где ответ и что с ним diff --git a/docs/architecture/13-tech-debt-anchors.md b/docs/architecture/13-tech-debt-anchors.md index 17355a1e..1aea9e75 100644 --- a/docs/architecture/13-tech-debt-anchors.md +++ b/docs/architecture/13-tech-debt-anchors.md @@ -16,7 +16,7 @@ ### [CONFIRMED_LOST] Строка 85 — пилот-преп добор: Bertalign GOLD-пары (D29.2в) · R2 shadow (D25.2) · exp08 v3 (D21.8) -Bertalign: grep -rni bertalign по eval/ и backend/ — 0 вхождений (нет ни кода, ни данных). exp08 v3: в docs/experiments/ существует только 08-cost-model-v2.md; его шапка (греп `Пере-съём заказан как exp08 v3`) прямо говорит «Пере-съём заказан как exp08 v3 (D21.8 … D25.8 …)» — т.е. заказан, не исполнен; в eval/ есть только cost_model_v2.py (v3-скрипта нет). Подтверждается и D-логом (D21): «→ exp08 v3 … до фиксации budget_usd-дефолтов Ф2» — висящее поручение, и 02-mvp-plan.md:34 «пере-съём exp08 v3» как открытый. Скоуп — пилот-преп-промт Ф2.5, дельта вписана в docs/POLYGON_PACKAGE4_SESSION_PROMPT.md:4. +Bertalign: grep -rni bertalign по eval/ и backend/ — 0 вхождений (нет ни кода, ни данных). exp08 v3: в docs/experiments/ существует только 08-cost-model-v2.md; его шапка (греп `Пере-съём заказан как exp08 v3`) прямо говорит «Пере-съём заказан как exp08 v3 (D21.8 … D25.8 …)» — т.е. заказан, не исполнен; в eval/ есть только cost_model_v2.py (v3-скрипта нет). Подтверждается и D-логом (D21): «→ exp08 v3 … до фиксации budget_usd-дефолтов Ф2» — висящее поручение, и `docs/architecture/02-mvp-plan.md:37`=`пере-съём exp08 v3` — как открытый (⚠ прежний голый якорь `:34` съехал, там пустая строка). Скоуп — пилот-преп-промт Ф2.5, дельта вписана в `docs/POLYGON_PACKAGE4_SESSION_PROMPT.md:4`=`exp08 v3 (D21.8)`. ### [CONFIRMED_LOST] Дописка к строке 59 — GLM context-overflow гард (finish=model_context_window_exceeded) @@ -162,7 +162,7 @@ grep sanitiz по backend/configs/pipeline-c2.yaml — 0 вхождений (exi ### Б-106 — тело строки 106 на 09.08.2026 -**Слой 3 НЕ достроен: контракт редактора = full-regen, а целевой — узкие мандаты + ДИФФЫ.** `09-target-architecture.md:121-126` дословно: «research/07 предписывает узкие мандаты + диффы, а не полную перегенерацию — сейчас ровно наоборот (4 мандата, full-regen), что и породило хвост инверсий»; целевой контракт — редактор правит anchored search/replace-спанами с детерминированным Go-apply (ограниченный blast-radius, дешевле, аудируемо, структурно omission-safe). Пак-16 построил петлю РЕМОНТА (починка флагнутого спана постфактум), а не diff-контракт роли ⇒ это разные вещи. **Строки не было ни одной** — дыра учёта, найденная сверкой 02.08 (грепы `diff`/`мандат`/`span` по бэклогу = 0). Смежное: арм Q4b «diff-fidelity+style редактор» (`exp15:108`) не прогонялся НИ РАЗУ, хотя трек B объявлен завершённым. **ЭМПИРИКА ПОЛУЧЕНА (D39.108, экспы 19/20):** дифф-контракт механически исправен (комплаенс 0.966 на боевой единице, аппликатор 15/15), но по замороженному гейту Q4b диффы ОТЛОЖЕНЫ (fidelity-trap 11/12; дороже full-regen на dspro×ru ×2.5–2.9 при невскрытой причине; D21.4/D21.10 закрыты явно). **Эксп-21 (D39.117):** полный regen выигрывает у точечного ремонта (`C2/A_law` −3.75 Holm 0.0006) — довод против диффов, НЕ опровержение: чинил дешёвый фиксер по предложению, а не сильный редактор узким мандатом; гейт «перепроверить до стройки» в силе, приоритет понижен +**Слой 3 НЕ достроен: контракт редактора = full-regen, а целевой — узкие мандаты + ДИФФЫ.** `docs/architecture/09-target-architecture.md:106`=`узкие мандаты + диффы` дословно: «research/07 предписывает узкие мандаты + диффы, а не полную перегенерацию — сейчас ровно наоборот (4 мандата, full-regen), что и породило хвост инверсий» (⚠ прежний голый якорь `:121-126` съехал на слой 5/6); целевой контракт — редактор правит anchored search/replace-спанами с детерминированным Go-apply (ограниченный blast-radius, дешевле, аудируемо, структурно omission-safe). Пак-16 построил петлю РЕМОНТА (починка флагнутого спана постфактум), а не diff-контракт роли ⇒ это разные вещи. **Строки не было ни одной** — дыра учёта, найденная сверкой 02.08 (грепы `diff`/`мандат`/`span` по бэклогу = 0). Смежное: арм Q4b «diff-fidelity+style редактор» (`exp15:108`) не прогонялся НИ РАЗУ, хотя трек B объявлен завершённым. **ЭМПИРИКА ПОЛУЧЕНА (D39.108, экспы 19/20):** дифф-контракт механически исправен (комплаенс 0.966 на боевой единице, аппликатор 15/15), но по замороженному гейту Q4b диффы ОТЛОЖЕНЫ (fidelity-trap 11/12; дороже full-regen на dspro×ru ×2.5–2.9 при невскрытой причине; D21.4/D21.10 закрыты явно). **Эксп-21 (D39.117):** полный regen выигрывает у точечного ремонта (`C2/A_law` −3.75 Holm 0.0006) — довод против диффов, НЕ опровержение: чинил дешёвый фиксер по предложению, а не сильный редактор узким мандатом; гейт «перепроверить до стройки» в силе, приоритет понижен ### Б-108 — тело строки 108 на 09.08.2026 @@ -174,7 +174,7 @@ grep sanitiz по backend/configs/pipeline-c2.yaml — 0 вхождений (exi ### Б-121 — тело строки 121 на 09.08.2026 -**archguard v2 (посадки приёмки D39.96 + §7-12/13 + §7-9). ⚠ Пункты (0а)/(0б) — РЕГРЕССИЯ против снесённого байт-гарда; дофикс ИСПОЛНЕН и принят D39.97 — (0а)/(0б)/(а) ЗАКРЫТЫ, плюс блокер type-param, ось имени и ложное срабатывание сверх промта; остаток строки — (б)/(в)/(г)/(д).** (0а) egressseam пропускает пакетную `llm.Complete(...)`: nil-`Selections` → молчаливый выход (`archguard.go:240-242`; фикс — fallback на `Uses`); (0б) пропускает интерфейс с llm-типами внутри композита (`Complete(ctx, []llm.LLMRequest)…` — `touchesPkg` не рекурсивен, `:79-82`); старый регекс `.Complete(` ловил обе формы; комменты «cannot be hidden» (`:250-253` и фикстура) фальсифицированы — переписать честно; (а) `runRequestSeam` обходит ТОЛЬКО `*ast.CompositeLit` (`archguard.go:197`): `var r pipeline.Request`+присваивание и `new(pipeline.Request)` проходят МОЛЧА — подтверждено на реконструкции: дыра ОБЩАЯ со старым гардом (не регрессия); фикс ~10 строк: симметрия ValueSpec/CallExpr со stage-сеамом + негативная фикстура, документирующая осознанные пропуски; (б) класс «встраивание · make+присваивание · дженерик-ноль» закрывается не свитчем, а ТИПОМ (нулевое значение `config.Stage` непригодно вне пакета); (в) политика build-тегов vet (сегодня default+live; чужой тег невидим — других в репо нет); (г) кандидат 4-й анализатор границы импортов — `backend/README.md:3` заявляет «проверяет `go list -deps`», что не автоматизировано ничем; (д) семь осознанных пропусков после дофикса 03.08 (принят D39.97; фикстуры БЕЗ want — покраснеют, когда начнут ловиться): llm.Ask-класс · пара внутри named-обёртки · встраивание/make/generic-zero · `internal/llm` исключён целиком (второй провод внутри адаптеров ловится только ревью) · внешние тест-пакеты · рефлексия (статикой не закрывается) · файлы за третьим сборочным тегом — всё, что закрываемо, закрывается типовым швом (б), не свитчем +**archguard v2 (посадки приёмки D39.96 + §7-12/13 + §7-9). ⚠ Пункты (0а)/(0б) — РЕГРЕССИЯ против снесённого байт-гарда; дофикс ИСПОЛНЕН и принят D39.97 — (0а)/(0б)/(а) ЗАКРЫТЫ, плюс блокер type-param, ось имени и ложное срабатывание сверх промта; остаток строки — (б)/(в)/(г)/(д).** (0а) egressseam пропускает пакетную `llm.Complete(...)`: nil-`Selections` → молчаливый выход (`archguard.go:240-242`; фикс — fallback на `Uses`); (0б) пропускает интерфейс с llm-типами внутри композита (`Complete(ctx, []llm.LLMRequest)…` — `touchesPkg` не рекурсивен, `:79-82`); старый регекс `.Complete(` ловил обе формы; комменты «cannot be hidden» (`:250-253` и фикстура) фальсифицированы — переписать честно; (а) `runRequestSeam` обходит ТОЛЬКО `*ast.CompositeLit` (`archguard.go:197`): `var r pipeline.Request`+присваивание и `new(pipeline.Request)` проходят МОЛЧА — подтверждено на реконструкции: дыра ОБЩАЯ со старым гардом (не регрессия); фикс ~10 строк: симметрия ValueSpec/CallExpr со stage-сеамом + негативная фикстура, документирующая осознанные пропуски; (б) класс «встраивание · make+присваивание · дженерик-ноль» закрывается не свитчем, а ТИПОМ (нулевое значение `config.Stage` непригодно вне пакета); (в) политика build-тегов vet (сегодня default+live; чужой тег невидим — других в репо нет); (г) кандидат 4-й анализатор границы импортов — `backend/README.md:3`=`go list -deps` заявляет «проверяется `go list -deps`», что не автоматизировано ничем; (д) семь осознанных пропусков после дофикса 03.08 (принят D39.97; фикстуры БЕЗ want — покраснеют, когда начнут ловиться): llm.Ask-класс · пара внутри named-обёртки · встраивание/make/generic-zero · `internal/llm` исключён целиком (второй провод внутри адаптеров ловится только ревью) · внешние тест-пакеты · рефлексия (статикой не закрывается) · файлы за третьим сборочным тегом — всё, что закрываемо, закрывается типовым швом (б), не свитчем ### Б-122 — тело строки 122 на 09.08.2026 diff --git a/docs/architecture/14-api-contract/README.md b/docs/architecture/14-api-contract/README.md index 18abf8bc..4b626d61 100644 --- a/docs/architecture/14-api-contract/README.md +++ b/docs/architecture/14-api-contract/README.md @@ -1334,7 +1334,7 @@ D39.152. **Замер объёма прозы** (пин зоны `openapi-typescript@7.13.0`, воспроизведён верификатором до байта): канон дал **+10 546 байт и +144 строк комментариев** в исходники фронта. Гипотеза «62 % этого — обоснование, которому место в компаньоне» пере-проверку НЕ прошла: из тринадцати заявленных блоков -выжил один. Итог трима: 152 758 → 152 002 байта. **Урок для следующей правки канона: норма — в +выжил один. **Своим решением, а не по находке, срезан ещё денежный хвост у `Book.chapters_done`** — он ничего не меняет в поведении клиента. Итог трима: 152 758 → 152 002 байта. **Урок для следующей правки канона: норма — в канон, довод — сюда; проверять не глазом, а диффом генерённого клиента.** --- diff --git a/docs/architecture/15-money-path.md b/docs/architecture/15-money-path.md index 4469a516..e2056a42 100644 --- a/docs/architecture/15-money-path.md +++ b/docs/architecture/15-money-path.md @@ -11,7 +11,7 @@ ## 1. Канон одним абзацем -Деньги видимы с первого вызова: телеметрия, потолки, явное согласие на пере-оплату (CLAUDE.md, цель 5). Леджер без потолка запрещён — Р7: книга обязана нести хотя бы один из `book_usd`/`day_usd` (`backend/internal/config/book.go:321`=`a ledger with no ceiling is forbidden`, текст валидатора: «a ledger with no ceiling is forbidden, Р7»). Суммы на пользовательский экран НЕ выходят — запрет D39.84, подтверждён D39.100/К-8 (дословно: «страница лимитов/использования в настройках (СТАТУС, не суммы — запрет денег на экране D39.84 в силе и НЕ superseded)» — `docs/architecture/05-decisions-log.md:232`=`СТАТУС, не суммы — запрет денег на экране`) и держится в контракте (`docs/architecture/14-api-contract/openapi.yaml`, греп `State of the credit balance. No window` — ⚠ номер не ставим: контракт переверстывается минорами, греп-форма дешевле поддержки (прежнее обоснование «файл двигает пак 0.9.0» протухло — пак заленджен 31.08)). Защита от перерасхода двойная и не зависит от событий: холд платформы делает кредит недоступным следующему прогону, а движок сам останавливается на потолке — «an overspend is impossible even while the platform is blind. The event stream is freshness only» (док-коммент `Hold` — `platform/internal/pgstore/credits.go`, греп `an overspend is impossible even`). +Деньги видимы с первого вызова: телеметрия, потолки, явное согласие на пере-оплату (CLAUDE.md, цель 5). Леджер без потолка запрещён — Р7: книга обязана нести хотя бы один из `book_usd`/`day_usd` (`backend/internal/config/book.go:321`=`a ledger with no ceiling is forbidden`, текст валидатора: «a ledger with no ceiling is forbidden, Р7»). Суммы на пользовательский экран НЕ выходят — запрет D39.84, подтверждён D39.100/К-8 (дословно: «страница лимитов/использования в настройках (СТАТУС, не суммы — запрет денег на экране D39.84 в силе и НЕ superseded)» — `docs/architecture/05-decisions-log.md`, греп `^## D39.100` → пункт К-8, дословная подстрока `СТАТУС, не суммы — запрет денег на экране`; ⚠ адресуем НОМЕРОМ: прежний голый `:232` убила эррата 02.09 в шапке, ровно как предсказывает строка бэклога 219) и держится в контракте (`docs/architecture/14-api-contract/openapi.yaml`, греп `State of the credit balance. No window` — ⚠ номер не ставим: контракт переверстывается минорами, греп-форма дешевле поддержки (прежнее обоснование «файл двигает пак 0.9.0» протухло — пак заленджен 31.08)). Защита от перерасхода двойная и не зависит от событий: холд платформы делает кредит недоступным следующему прогону, а движок сам останавливается на потолке — «an overspend is impossible even while the platform is blind. The event stream is freshness only» (док-коммент `Hold` — `platform/internal/pgstore/credits.go`, греп `an overspend is impossible even`). ## 2. Деньги ДВИЖКА (зона `backend/`) diff --git a/docs/architecture/16-events-emitter.md b/docs/architecture/16-events-emitter.md index f028c2af..502011a5 100644 --- a/docs/architecture/16-events-emitter.md +++ b/docs/architecture/16-events-emitter.md @@ -10,7 +10,7 @@ **Что.** Машинный канал живого статуса движок→платформа: NDJSON-журнал `events.jsonl` в каталоге книги — словарь-enum со стабильными типами, version-хендшейк первой строкой (правило terraform), плотная нумерация `seq`, событие потолка и событие денег. Заказ жил строками бэклога **103** (эмиттер) и **165** (различимые exit-коды); обе ЗАКРЫТЫ D39.131 и из живого бэклога сняты — дословные формулировки заказа, если понадобятся, лежат в архивных слайсах `../archive/PROGRESS-*.md`. -**Зачем две ноги.** (а) *Свежесть статуса* — слово владельца 08.08: «эмиттер нужен СВЕЖЕСТИ статуса и деньгам шва, не первым экранам» (D39.119 п.1); резерв на время без него — периодический `status --json`-резюнк. (б) *Деньги шва*: без события потолка «экран покажет „ошибка“ там, где верно „остановлено: лимиты“» (PD-113), а после поправки формулы потолка (D39.123, PD-158) стоп по потолку = ровно исчерпание холда, поэтому цена неразличимости выросла. +**Зачем две ноги.** (а) *Свежесть статуса* — слово владельца 08.08: «эмиттер нужен СВЕЖЕСТИ статуса и деньгам шва, не первым экранам» (D39.119 п.1); резерв на время без него — периодический `status --json`-резюнк. (б) *Деньги шва*: без события потолка «экран покажет „ошибка“ там, где верно „остановлено: лимиты“» (PD-113), а после поправки формулы потолка (D39.123, PD-158) стоп по потолку = ровно исчерпание холда, поэтому цена неразличимости выросла (⚠ неразличимость вскрыта **приёмкой раннера на РЕАЛЬНОМ tmctl** — фейк пробы умирал от сигнала; дословный заказ — `docs/archive/prompts/BACKEND_EMITTER_SESSION_PROMPT_2026-08-10.md:96`=`Новые exit-коды tmctl`). **Что эмиттер НЕ решает** (и не решал): реконсилятор и свип — платформа (строки 138·139 закрыты, D39.123 п.3) · write-ahead intent / `uncertain`-эскроу / `closing` — строка 136 бэклога · пиннинг версии бинаря на прогон — исполняется резюмом (PD-143/134 закрыты) · движковая оценка $/глава — строка 166 · тейлер/декодер платформы — `platform/internal/ingest/`, эмиттер пишет ПОД их контракт. @@ -66,4 +66,4 @@ 1. **Знаменатели голосов панелей `research/25` различаются между вариантами** (0/15 · 0/~18) — это РАЗНЫЕ плечи панелей, не усреднять. Оговорка нужна ровно там, где §2 цитирует счёт голосов отвергнутых альтернатив. 2. Тела D39.84/D39.85/D39.100 вошли сюда через цитаты D39.106 и доккомменты кода — при сомнении открывать первоисточники (живой D-лог/слайсы), а не эту сборку. -⚠ **Снято как отработанный хендофф** (D39.131, `9cfe080`): §5 «пять открытых развилок дизайна» — все пять решены (формат = одиночный JSONL · политика PD-60 = громкая деградация · fsync каталога один раз при создании · значение exit-кодов · словарь, отвеченный диффом), ответы читать в `backend/internal/runevents/journal.go` и `runevents.go`; §6 «чек-лист входного чтения эмиттер-сессии» (ратифицирован D39.123 п.4) — исполнен, ни одной внешней ссылки на него не было; из §7 «оговорок сборки» две первые сняты стройкой (сверка словаря с `research/23` сделана диффом; «строка события в той же SQLite-транзакции, что чекпойнт» — теперь факт кода `backend/internal/store/outbox.go`, а не формула). \ No newline at end of file +⚠ **Снято как отработанный хендофф** (D39.131, `9cfe080`) — речь о ПРЕЖНИХ разделах этого файла, нумерация с тех пор сдвинулась и живой §5 выше — другой (⚠ испр. 02.09: надгробие называло их «§5·§6·§7» как действующие). **Прежний раздел развилок** — «пять открытых развилок дизайна», все пять решены (формат = одиночный JSONL · политика PD-60 = громкая деградация · fsync каталога один раз при создании · значение exit-кодов · словарь, отвеченный диффом), ответы читать в `backend/internal/runevents/journal.go` и `runevents.go`. **Прежний чек-лист входного чтения эмиттер-сессии** (ратифицирован D39.123 п.4) — исполнен, ни одной внешней ссылки на него не было. **Из прежних «оговорок сборки»** две первые сняты стройкой (сверка словаря с `research/23` сделана диффом; «строка события в той же SQLite-транзакции, что чекпойнт» — теперь факт кода `backend/internal/store/outbox.go`, а не формула). \ No newline at end of file