From d7fb918a1c1b0e5e128fe08cac91cdef7f7afcfd Mon Sep 17 00:00:00 2001 From: heaven Date: Sat, 19 Sep 2026 00:12:58 +0300 Subject: [PATCH] Rewrite the chapter-boundary pack around boundaries as a union and cuts inside a document, record its issue, and align the advisor ceiling with the ratified note --- CLAUDE.md | 2 +- ...ACKEND_CHAPTER_STRUCTURE_SESSION_PROMPT.md | 627 ++++++++---------- docs/BACKLOG.md | 2 +- docs/NEAR_TERM_PLAN.md | 2 +- docs/README.md | 2 +- docs/architecture/05-decisions-log.md | 54 +- docs/orchestrator-norms-scratchpad.md | 4 +- 7 files changed, 338 insertions(+), 355 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index bb01f310..a29c7720 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -350,7 +350,7 @@ Go-бэкенд издательского художественного пер ровно там, где предмет. Вопрос себе: «сколько раз этот файл переписывается за прогон и какой из разов я сейчас читаю?» ⭐ **Пришло письмо «всё закрыто» — иди перечитывать СВОИ утверждения о закрытом, а не чужие правки.** - ⛔ **Fable 5 — ПОТОЛОК 1–2 АГЕНТА НА СЕССИЮ, слово владельца 11.09: «я не разрешаю больше 1-2 на сессию».** Прежняя редакция называла это рекомендацией — она отозвана. Модель задавай агенту ЯВНО и знай, сколько их у тебя работает. ⚠ И форма важнее числа: **одному агенту с ПОСТОЯННЫМ контекстом дослылают вопросы, а не поднимают второго** — контекст и есть ценность. Опус-субагенты потолком не ограничены, но тратятся так же. ⭐ **Дополнение владельца 11.09: потолок относится к КАЖДОЙ сессии, и зонная сессия тоже вправе держать СВОЕГО фабла-советчика — ОДНОГО.** Слово дословно: «разрешаю 1 фабла на 1 сессию, ну как у тебя». ⇒ промт зоны это НАЗЫВАЕТ: как поднять (`model: "fable"` явно), о чём спрашивать (сомнение · развилка · «не построено ли уже» · «не противоречит ли ратифицированному»), и что он СОВЕТЧИК, а не источник истины — его посылки проверяются деревом. + ⛔ **Fable 5 — ПОТОЛОК 1–2 АГЕНТА НА СЕССИЮ, слово владельца 11.09: «я не разрешаю больше 1-2 на сессию».** Прежняя редакция называла это рекомендацией — она отозвана. Модель задавай агенту ЯВНО и знай, сколько их у тебя работает. ⚠ И форма важнее числа: **одному агенту с ПОСТОЯННЫМ контекстом дослылают вопросы, а не поднимают второго** — контекст и есть ценность. Опус-субагенты потолком не ограничены, но тратятся так же. ⭐ **Дополнение владельца 11.09: потолок относится к КАЖДОЙ сессии, и зонная сессия тоже вправе держать СВОЕГО фабла-советчика — ОДНОГО.** Слово дословно: «разрешаю 1 фабла на 1 сессию, ну как у тебя». ⚠ **СМЯГЧЕНО 17.09 нотой `D39.258` п.9 (журнал бьёт этот файл):** зонной сессии — ДО ДВУХ советчиков с постоянным контекстом, и советоваться предписано на ПРОЕКТИРОВАНИИ и на ПРИЁМКЕ, а не только при затруднении; карта чтения промта — минимум, `docs/` грепается в любое время. Отставание этой строки дважды дало неверный промт (18.09). ⇒ промт зоны это НАЗЫВАЕТ: как поднять (`model: "fable"` явно), о чём спрашивать (сомнение · развилка · «не построено ли уже» · «не противоречит ли ратифицированному»), и что он СОВЕТЧИК, а не источник истины — его посылки проверяются деревом. - **Git-координация мультисессий:** - **Коммитит только оркестратор.** Сессии зон — бэкенд, полигон, фронт, платформа — не коммитят: своё дерево готовят и передают на лендинг (исключение: пре-рег фризы полигона). Чужую зону не трогает НИКТО. - **Форма коммита — ТОЛЬКО с явным списком путей: `git commit -- <путь> <путь>`.** Причина механическая: голый `git commit` уносит **ВЕСЬ индекс**, включая чужие застейдженные файлы, и чужая работа уезжает под твоим сообщением. Pathspec-форма индекс не трогает. diff --git a/docs/BACKEND_CHAPTER_STRUCTURE_SESSION_PROMPT.md b/docs/BACKEND_CHAPTER_STRUCTURE_SESSION_PROMPT.md index 47d1b481..bad5caf8 100644 --- a/docs/BACKEND_CHAPTER_STRUCTURE_SESSION_PROMPT.md +++ b/docs/BACKEND_CHAPTER_STRUCTURE_SESSION_PROMPT.md @@ -1,451 +1,382 @@ -# Промт бэкенд-сессии: ГРАНИЦА ГЛАВЫ — ФАКТ КНИГИ, А НЕ ДОГАДКА ДВИЖКА +# Промт бэкенд-сессии: ГРАНИЦА ГЛАВЫ — СКЛЕИТЬ ТО, ЧТО ДВИЖОК УЖЕ ЗНАЕТ -> Выдан оркестратором очереди №23. Пак **$0**. Зона записи — `backend/`. -> Ты не коммитишь: дерево передаётся оркестратору на лендинг. +> Оркестратор очереди №23. Пак **$0**, платных вызовов в нём нет. Зона записи — `backend/`. Ты не коммитишь: +> дерево передаётся оркестратору на лендинг. Именование пака и его границы ратифицированы нотой **`D39.270`** +> (греп `^## D39.270` в `docs/architecture/05-decisions-log.md`); при расхождении промта с нотой побеждает нота. > -> ⛔ **Это НЕ пак «починить осколки английской книги».** Осколки — симптом, и самый дешёвый из трёх. -> Предмет пака — **кто и на каком основании решает, где начинается глава**. +> Предмет пака — **кто и на каком основании решает, где начинается глава и как она называется.** Осколки +> оглавления английской книги — самый дешёвый симптом, а не предмет. --- ## 1. Какая проблема и что решит твой результат -Движок переводит книги мультиагентным пайплайном. Пары языков — ДАННЫЕ, не код; ревью-вопрос по умолчанию: -«заработает ли пара, которой в репо ещё НЕТ, без правки Go?». +Движок переводит длинные книги мультиагентным пайплайном. Пары языков — ДАННЫЕ, а не код; ревью-вопрос по +умолчанию: «заработает ли пара, которой в репо ещё НЕТ, без правки Go?». -Скоро пойдёт платный холодный прогон двух книг: около 20 глав китайской и равный по токенам срез английской. -⛔ **Слово владельца, под которым выдан этот пак:** «цель — не бежать поскорее приступить к холодному -прогону, а подготовить бэкенд так, чтоб этот холодный прогон исполнить **максимально правильно**. Сколько -паков и бэклога нам для этого нужно закрыть, не очень важно. Халтурить не надо, подгонять тоже ничего не -надо, спиливаем долг из бэкенда, реализуем актуальный, нужный, чистый архитектурно код». +Скоро идёт платный холодный прогон двух книг через API платформы: около 20 глав китайской и равный по +токенам срез английской — `books/Kristoff_Jay_-_Empire_of_the_Vampire_3_-_Empire_of_the_Dawn.epub` (EPUB 2.0, +навигация — `toc.ncx`, `nav.xhtml` нет). ⛔ **Слово владельца, под которым выдан пак:** «цель — не бежать +поскорее приступить к холодному прогону, а подготовить бэкенд так, чтоб этот холодный прогон исполнить +**максимально правильно**. Халтурить не надо, подгонять тоже ничего не надо, спиливаем долг из бэкенда, +реализуем актуальный, нужный, чистый архитектурно код». -**Что сломано, замерено мною по книге прогона (пере-снимешь своим прибором — все числа воспроизводимы $0).** -Целей навигации **71**: шесть ярлыков частей (`BOOK ONE`…`BOOK SIX`) и **65 ярлыков глав** вида -`Chapter XIX. A Taste of Home`. Издательский конвертер разрезал страницу оглавления на отдельные файлы и -объявил навигационную цель на каждый осколок ⇒ **62 цели из 71 указывают во ВТОРУЮ половину spine** (позиции -целей 8…124 при 126 документах, медиана 89), тогда как проза лежит в первой. +**Корень, найденный владельцем одной фразой** — «у нас есть статический код, который смотрит, глава ли это и +как она названа, там как-то это всё должно склеиваться». Замер подтвердил дословно: диспетчер ингеста отдаёт +грамматику источника только текстовому пути — +`backend/internal/chunk/ingest.go:243`=`func ingestTXT(p, encoding, sourceLang string, st *lang.SourceStructure)` — +а `backend/internal/chunk/ingest.go:678`=`func ingestEPUB(p string, im *lang.InlineMarkup)` её не получает +вовсе. ⇒ механизм, умеющий сказать «это глава и вот её имя», работает на одном пути из двух; на EPUB границу +единолично назначает навигация издателя. -⛔ **И вот замер, который переворачивает саму картину «навигация указывает не туда»: документов spine БЕЗ -навигационной цели — 55 из 126, и это ВСЯ ПРОЗА КНИГИ** (`index_split_005`…`_043`, от 9 до 157 тыс. знаков -каждый). Навигация адресует осколки оглавления и ровно четыре прозаических документа. ⇒ говорить «цели указывают -не туда» мягко: **текста книги навигация почти не адресует вообще.** +**Что эта навигация делает с книгой прогона** (всё снято $0 питоном по архиву; пере-снимешь своим прибором): -**Тела целей, разбиение полное и сумма сходится с 71:** **60** побуквенно равны своему ярлыку · **7** коротки, -но ярлыку НЕ равны — два титула частей (`BOOK ONE`+`DEATHSEEKER`, `BOOK FOUR`+`THIS BLACKENED VEIL`) и пять -осколков оглавления, у которых вторая строка есть имя СЛЕДУЮЩЕЙ части (`Chapter XIX. A Taste of Home` + -`Book Three. To Kill a King`) · **4** несут прозу (`BOOK TWO/THREE/FIVE/SIX`, 14–82 тыс. знаков). +| что | число | +|---|---| +| целей навигации | **71** = 6 ярлыков частей (`BOOK ONE`…) + 65 ярлыков глав (`Chapter XIX. A Taste of Home`) | +| тела целей | **60** побуквенно равны своему ярлыку · **7** коротки и НЕ равны (2 титула частей с подзаголовком · 4 осколка оглавления, чья вторая строка — имя следующей части · 1 осколок с хвостом оглавления: `Dawn · Acknowledgments · Also by · About the Author · Copyright`) · **4** несут прозу | +| документов spine без навигационной цели | **55 из 126** = 35 прозаических (≥9 тыс. знаков) + 20 прочих; среди прочих `index_split_058` и `_124` — ТЕКСТ оглавления вне навигации | +| печатное оглавление книги (`058`, осколки `059…123`, второе оглавление в `124`) | Dramatis Personae · Sunset · **81** «Chapter» · Dawn · служебные | +| форма главы в прозе | римское числительное отдельным абзацем, затем имя прописными, затем проза | +| абзацев, чей текст — голое римское числительное | **84**: у 81 имя следом, у 3 нет — все три в разделе `SUNSET` (`006`), где за номером сразу проза | +| разделов БЕЗ номера | 2: `SUNSET` (`006`) и `DAWN` (`049`, ~13.7 тыс. знаков; открыт абзацем `DAWN`) | +| номеров глав в документах, у которых ЕСТЬ цель навигации | **12** (`015`:1 · `025`:5 · `033`:3 · `041`:3) | +| документов, несущих 2 и больше глав | **28** (по 2–7) | +| ярлык навигации против «номер + имя» из прозы | побайтно **0 из 81**; при нормализации регистра и апострофа **65 из 81** ⇒ 16 глав навигация не называет вовсе | -⛔ **А настоящих глав — 81, плюс пролог, и это первое, что я ставил неверно ДВАЖДЫ.** Форма главы: римское -числительное, затем имя прописными тем же классом, затем проза другим классом. Замер: голых римских -числительных **84**, из них **81 имеет имя следом** и **3 не имеют** — все три в открывающей секции `SUNSET`, -где за номером идёт сразу проза. ⇒ **«84 главы» есть ВЫВОД прибора, а не замер книги**: собственное оглавление -книги даёт «Sunset» одной строкой и 81 строку «Chapter». Контроль, доказывающий, что прибор читал книгу, — -абзацев с классом **11 397** (счётчиком по `]*class="…"`; другой парсер на тот же вопрос даёт 11 522 — -подписывай способ счёта рядом с числом). -⛔ **СУДЬБА ПРОЛОГА — РАЗВИЛКА, И РЕШИТЬ ЕЁ ОБЯЗАН ТЫ, А НЕ УМОЛЧАНИЕ ПРАВИЛА.** Голое числительное разрежет -`SUNSET` на три безымянных главы, а единственное имя пролога уедет в преамбулу первой из них. Варианты: **81 + 3 -безымянных = 84** или **81 + 1 «Sunset» = 82**, и второй требует ТРЕТЬЕЙ формы заголовка (имя без числительного), -которой у грамматики сегодня нет. Назови выбор и довод; приёмочное число — тот, который ты назвала. -⚠ И мой первый замер дал **3** вместо 84, потому что регексп требовал `class` первым атрибутом, а у -большинства первым стоит `id`. **Отрицательный замер здесь особенно дёшев и особенно лжив — печатай -контрольную величину рядом.** +Контроль, доказывающий, что прибор читал книгу: абзацев с атрибутом класса — 11 397 (счёт регекспом +`]*class=`; другой парсер на тот же вопрос дал 11 522 — подписывай способ счёта рядом с числом). -⭐ **ГЛАВНОЕ, и ради этого пак переписан.** Ярлык навигации «Chapter IV. Unforgiven» есть СКЛЕЙКА того, что -проза держит двумя абзацами — `IV` и `UNFORGIVEN`. ⚠ **Склейка НЕ побайтная, и без этой оговорки замер даёт -ноль:** ярлык в Title Case, проза капсом, апостроф типографский ⇒ побайтно **0 из 81**, с нормализацией -регистра и апострофа — **65 из 81**. Оставшиеся **16 глав навигация не называет вовсе** (их строки оглавления -лежат в документе без навигационной цели). ⇒ **навигация несёт правильные ИМЕНА и неправильные -АДРЕСА; проза несёт правильные АДРЕСА и расщеплённое имя.** Ни один источник не лжёт целиком, и ни одного не -хватает в одиночку. +⭐ **Сводка одной строкой, и это сердце пака:** навигация несёт правильные ИМЕНА и неправильные АДРЕСА; проза +несёт правильные АДРЕСА и расщеплённое имя. Ни один источник не лжёт целиком, и ни одного не хватает одного. -⛔ **Отсюда — чего в этом паке делать НЕЛЬЗЯ, и я сам чуть этого не заказал:** нельзя объявить навигацию -врущей и выбросить её. Прежняя редакция промта говорила «настоящих глав шесть» и «навигация о заголовках не -знает» — **оба утверждения ложны**, и сессия, получив 84, сверила бы их с «шестью» и решила, что верное -правило неверно. - -⇒ Задача — не «поймать мусор эвристикой» и не «отвергнуть навигацию», а **склеить два источника**: АДРЕС -берётся у грамматики, ИМЯ — у того, кто его несёт. Твой результат: английская книга режется по своим -настоящим главам, каждая получает имя, и достигнуто это ДАННЫМИ книги, а не веткой в Go. +**Твой результат:** английская книга режется по своим настоящим главам, каждая получает имя, книга без этого +явления не меняется ни на байт — и всё это без ветки по языку или книге в Go. --- ## 2. Зона записи и git -Пишешь только в `backend/`. Чужие зоны читать можно, править нельзя. Исключение — своя секция в -`docs/PROGRESS.md`. Ты не коммитишь: дерево передаётся на лендинг. В дереве могут работать другие сессии — -их незакоммиченные файлы не трогай. - +Пишешь только в `backend/` и в свою секцию `docs/PROGRESS.md`. Чужие зоны (`platform/`, `frontend/`, +`eval/`, прочие `docs/`) читать можно, править нельзя. Не коммитишь; в дереве могут работать другие сессии — +их незакоммиченное не трогай. Фоновое гасишь по своему PID, а не по имени команды. ⛔ **НИКОГДА не читай `.env` и `.env.*`** — там боевые ключи. +Артефакты: что должно пережить рестарт — в РЕПОЗИТОРИЙ (доказательная база уедет в `docs/archive/reports/` при +приёмке); питон-пробы и копии дерева — в скретчпаде, не в репо; базы прогонов — только на чтение +(`python3` + `sqlite3.connect('file:<путь>?mode=ro', uri=True)`). --- -## 3. Карта чтения — пять позиций, и она ЗАКОН +## 3. Карта чтения — минимум из пяти позиций -**Код-факты добываешь САМА: адреса ниже — отправные точки, а не истина.** +Карта — МИНИМУМ, а не потолок (`D39.258` п.9): `docs/`, `research/`, `experiments/` грепай в любое время. +Код-факты добываешь САМА: адреса в промте — отправные точки, а не истина. 1. `CLAUDE.md` — канон, цели, гардрейлы. -2. `backend/docs/CHAPTER_STRUCTURE_DESIGN.md` — дизайн-оф-рекорд предмета, **2062 строки**. ⛔ Читай **§7.1-бис · §7.2 · §7.3 · §7.4 · §8.1 · §8.2** и шапку. ⚠ **§9 и §11 НЕ читай:** там тринадцать пинов - БОЛЬШОГО перекроя с миграциями и вопросы владельца по нему — §4.5 выносит его из пака, и чтение втянет тебя - в предмет, которого тебе не заказывали. **Статус документа — «ПРЕДЛОЖЕНИЕ, НЕ РАТИФИЦИРОВАНО»**: четыре - круга опровержения, сходимости нет; предметная часть устояла, механика исполнения — нет. ⇒ ссылаться на - него как на решённое НЕЛЬЗЯ; брать оттуда форму — можно и нужно. -3. `backend/internal/chunk/epubtoc.go` — разбор навигации и группировка документов. -4. `backend/internal/lang/structure.go` + `backend/internal/chunk/ingest.go` — грамматика заголовка и её - потребители. -5. `docs/BACKLOG.md`, ряды **283 · 302 · 303 · 201 · 284**. +2. `backend/docs/CHAPTER_STRUCTURE_DESIGN.md` — шапка и §7.1-бис · §7.2 · §7.3 · §7.4 · §8.1 · §8.2. Статус + документа — **ПРЕДЛОЖЕНИЕ, НЕ РАТИФИЦИРОВАНО** (`D39.245`: четыре круга без сходимости; устояла предметная + часть «глава — идентичность», механика — нет). Брать оттуда ФОРМУ можно и нужно, ссылаться как на решённое — + нельзя. Большой перекрой его §9 (ряд 161) этот пак НЕ строит. +3. `backend/internal/chunk/` — `ingest.go` и `epubtoc.go`: диспетчер, оба пути, разбор навигации, группировка. +4. `backend/internal/lang/structure.go` — грамматика заголовка, её лестница загрузки и отпечаток. +5. `docs/BACKLOG.md`, ряды **303 · 346 · 283 · 284 · 201 · 302**. --- ## 4. Работа -### 4.0 ⛔ КОРЕНЬ: ДВА ПУТИ РЕШАЮТ ГРАНИЦУ ГЛАВЫ ПО-РАЗНОМУ И НЕ СПРАШИВАЮТ ДРУГ ДРУГА +### 4.0 Что ратифицировано и вложено сюда, чтобы не открывать ноты -Я ставил задачу дважды и дважды неверно: сперва обошёл предмет срезом, потом искал, какой эвристикой ловить -мусор. Верная постановка пришла от владельца одной фразой — «у нас есть статический код, который смотрит, -глава ли это и как она названа, там как-то это всё должно склеиваться», — и замер её подтвердил. +- **Этот пак есть «пак 2» по ряду 303** (`D39.270` п.1). Запрет `D39.224` п.7 («ось „обязательность юнита" вне + пака 2 не трогать») условен и этим паком **исполняется, а не снимается**: ось трогать можно и нужно. Прочие + запреты того же пункта действуют: `Runner` не переписывать, `internal/pipeline` не дробить. +- **Ряд 346 половина (б) едет в этом паке** (`D39.270` п.7) — отступление от `D39.224` п.4(а) («шаги 2+3 — одна + перенарезка») ратифицировано там же; цена второй перенарезки $0 при условии `D39.224` п.5. +- **Стандарт владельца** (`D39.258` п.3): «согласно нашим проектным высоким стандартам по решению проблемы + художественного перевода»; «не хакайте плохие решения или те, что не работают, пишите чистый код и там, где + надо, рефакторинг»; техдолг не копить. ⇒ где чистое решение требует перестройки, заказана перестройка, и + отчёт называет, что отрефакторено и почему. +- **Слово владельца о языке и книге:** «Бэкенд не должен иметь конкретных механизмов под язык\книгу, максимум + в данных, и то они так же должны хорошо отрабатывать, где этих французских слов нет». +- **Холодный прогон идёт через API платформы, целиком** (слово владельца). Это задаёт §4.2. -**Замер, пере-снимешь своим прибором.** Диспетчер ингеста получает грамматику источника и отдаёт её **только -одному из двух путей**: -- `backend/internal/chunk/ingest.go:243`=`func ingestTXT(p, encoding, sourceLang string, st *lang.SourceStructure)` - — грамматику **получает**; -- `backend/internal/chunk/ingest.go:678`=`func ingestEPUB(p string, im *lang.InlineMarkup)` — **не получает - вовсе**, только инлайновую разметку. +### 4.1 РОВНО ТАК: правила, которые следуют из замера -⇒ **Статический код, который умеет сказать «это глава и вот её имя», построен и работает — на одном пути из -двух.** На пути EPUB его никто не спрашивает: там границу единолично назначает навигация издателя. Отсюда -**71 «глава» вместо 84 настоящих**. +**(а) ДОКУМЕНТ, ЧЬЁ ТЕЛО РАВНО ЕГО ЯРЛЫКУ, — НЕ ГЛАВА, НО ИМЯ ОН НЕСЁТ.** Это тождество, а не порог. +Исключается **существующим каналом** — `backend/internal/chunk/ingest.go:79`=`Excluded NAMES every service page that was not read` +(имя документа, роль, размер; инвариант сохранения его уже учитывает) — с НОВОЙ ролью. Отдельный счётчик не +заводить: код объясняет почему — `backend/internal/chunk/ingest.go:81`=`A NUMBER HERE WOULD HIDE THE ONE THING WORTH SEEING`. +Докблок `backend/internal/chunk/epubtoc.go:289`=`NO DOCUMENT IS DROPPED HERE` переписывается тем же движением и +называет условие, при котором вывод держится. +⛔ **Условие, без которого исключение есть пропуск текста** (`D39.205`: «без пропусков»; пропущенный кусок главы — +критический): исключение ничего не теряет, ТОЛЬКО если ярлык сохранён там, где его увидит читатель. Сегодня +он туда не доезжает (§4.3). ⇒ исключай тождество, чей ярлык СОПОСТАВЛЕН заголовку в прозе, либо назови другое +условие — и поставь пин на книгу 1:1, где тождественная страница «PART ONE» стоит перед главой со своей целью: +её текст обязан уцелеть. +⛔ Порога «почти равно» не заводить. **Остаток решается, а не называется:** 7 коротких не-тождеств и документы +`058`/`124` — у каждого исход (граница · преамбула · исключение с ролью) с доводом и числом. -⛔ **А вот пустой детерминированный заголовок сюда НЕ относится, и я едва не свалил его в ту же кучу.** -Он пуст по ДРУГОЙ причине, и твой пак его не заполнит: шаблон берётся из пар-данных -(`backend/internal/chunk/chunker.go:131`=`An absent TEMPLATE`), а у английской пары файла нет вовсе — -в `backend/configs/langpacks/en-ru/` лежат `inline-markup.txt` и `terminology.txt`, и всё -(у `zh-ru` `heading.txt` есть). ⇒ **либо назови «детерминированный заголовок для en — не результат этого -пака», либо закажи `en-ru/heading.txt` ДАННЫМИ** и скажи, как это трётся о ряды 201 и 284. Чего нельзя — -оставить его в причинной цепи: тогда отчёт пообещает то, чего правка не делает. +**(б) ГРАНИЦЫ — ОБЪЕДИНЕНИЕ ДВУХ НАБОРОВ.** Цели навигации, пережившие (а), плюс заголовки грамматики В ЛЮБОЙ +позиции, в том числе внутри документа, у которого есть цель; совпавшие позиции склеиваются, и **имя на совпавшей границе берётся у заголовка грамматики**, а ярлык части +решается судьбой титула (§4.2): у 4 частей из 6 титул делит документ с главой I (`015` · `025` · `033` · `041`), +и правило «ярлык ОТКРЫВШЕГО документа» назвало бы главу I второй части «BOOK TWO». ⚠ «Грамматика +только там, где навигация молчит» теряет 12 глав в четырёх документах с целью. Контроли: isekai — 44 главы до +и 44 после; Кристофф — 12 номеров в документах с целью разрезаны. -⭐ **И ЭТОТ ПАК ЕСТЬ «ПАК 2» ПО РЯДУ 303 — объявляю прямо, потому что без этого ты упрёшься в ратифицированный -запрет.** `D39.224` п.7 велит «ось „обязательность юнита" вне пака 2 не трогать (носитель — строка 303)», а сам -ряд 303 называет себя «названным ВХОДОМ в пак 2». ⇒ **запрет снимается ИМЕННО ЭТИМ паком, и ось трогать -можно.** Предмет 303: `detectChapterUnit` итерирует `UnitOrdered` и без юнита возвращает 0, поэтому грамматика -вида «Chapter 12» (маркер + номер, без юнита) книгу не режет — хотя чанкер такой заголовок СНЯТЬ уже умеет. -Форма лечения набросана в дизайне §8.2 (доминанта над ФОРМАМИ заголовка, «без юнита» — последний кандидат); -она НЕ ратифицирована, и ты вправе предложить другую с доводом. +**(в) РЕЗКА ВНУТРИ ДОКУМЕНТА — В ПАКЕ, потому что без неё книгу не разрезать** (28 документов по 2–7 глав). Она +ломает три допущения EPUB-пути, построенных на целых документах; для каждого назови, как оно держится: +- имя главы — ярлык ОТКРЫВШЕГО документа: `backend/internal/chunk/ingest.go:925`=`The chapter's source title is the label of the document that OPENED it`; +- инвариант «глава — ровно её документы»: `backend/internal/chunk/ingest.go:949`=`a chapter is EXACTLY its documents plus the separators`; +- номер главы у ruby-чтений, от которого зависит `since_ch` памяти: `backend/internal/chunk/ingest.go:961`=`The chapter number ruby carries MUST equal the number SplitChunks assigns`. +Обходчик `backend/internal/chunk/ingest.go:1155`=`func extractXHTML(data []byte, ir *inlineRules)` отдаёт ruby +без позиции и НЕ трогается (четыре пина байт-паритета, ошибка тихая); если без него нельзя — пинг, а не правка. +⚠ Ряд 302 в форме «якоря навигации внутри документа» НЕ строится (у этой книги фрагментов 0); резка по грамматике +на извлечённом тексте — строится. -⚠ **А вот «283 и 303 — один шов» было моей натяжкой, и её сними.** Это РОДСТВЕННЫЕ, но разные предметы: 303 — -текстовый резак ингеста; 283 — БИЛДЕР ВЫДАЧИ (`backend/internal/bookfile/`), делающий главу из каждого -документа spine у читалки человека. Общее у них — «грамматика не участвует там, где решают границу», и этого -довода достаточно; выдавать их за одну строку значит обещать закрыть 283, чего этот пак не делает. +**(г) ТИТУЛ ЧАСТИ ОСТАЁТСЯ ГРАНИЦЕЙ.** Сегодня его спасает подзаголовок; титул без подзаголовка был бы +тождеством, и (а) сняло бы границу целой части молча. Пин: тождественный титул, за которым идут документы без +целей навигации ⇒ граница сохраняется. -### 4.1 РОВНО ТАК: грамматика участвует на ОБОИХ путях, а навигация остаётся источником ИМЁН +**(д) ПРОВЕНАНС СМЕШАННОЙ НАРЕЗКИ НАЗЫВАЕТСЯ.** Сегодня метка утверждает, что границы провёл ровно один путь — +`backend/internal/chunk/ingest.go:186`=`exactly one of them drew every boundary`; после пака это ложь. Платформа +доверяет только `detected` (`platform/internal/ingest/manifest.go:284`=`IS DELIBERATELY NOT — which is the opposite`), +и от метки зависит, в главах или в знаках пользователь видит заказ (`D39.196` п.1). ⇒ назови метку, словарь +расширяй аддитивно, пин на метку; строкой отчёта — что увидит форма заказа. -**Предмет пака — склеить существующие механизмы, а не построить третий.** Грамматика даёт АДРЕС границы, -навигация даёт ИМЯ. Ни новой эвристики, ни порога, ни ветки по языку. +**(е) ЕДИНИЦА ПРАВИЛА — АБЗАЦ, А НЕ СТРОКА.** Существующая машина заголовков читает СТРОКИ +(`backend/internal/chunk/ingest.go:289`=`for _, ln := range strings.Split(chapter`), а исходник держит переводы строк +внутри абзаца: по строкам голых римских числительных 104, из них **20 ложных «I» в стихах** («KNOW THEE, WHO | I +| AM»). 84 по строкам на английской паре выходит лишь потому, что глиф курсива пары превращает «I» в `*I*` — +верный ответ неверным методом. ⇒ правило не вправе зависеть от данных пары; тестовый `ingest(p)` передаёт +разметку `nil` — проверь на нём. -**РЕШИ САМА** форму проводки и то, как два источника сводятся в один ответ. **Жёстко задаю четыре правила, и -каждое — следствие замера, а не вкус:** +**(ж) КАКАЯ СИСТЕМА СЧИСЛЕНИЯ — РЕШАЮТ ДАННЫЕ ГРАММАТИКИ; КАК ЕЁ ЧИТАТЬ — ОБЩИЙ АЛГОРИТМ.** Класс числительного +сегодня зашит в Go (`backend/internal/lang/structure.go:75`=`s.headerRE = regexp.MustCompile`): арабские плюс CJK +из встроенного `cjk-section.txt`. Выбор системы и её таблица (символ или слово → значение) — **новым ключом в +`structure.txt` языка источника**, со своим отпечатком в крое. Алгоритм системы (аддитивно-вычитательный для +римских, составной словарный для числительных-слов) — Go, как уже позиционный CJK-парсер `parseSectionNumeral`. +⛔ **НЕ через `numeral.txt`**: этот файл — канал МАЙНЕРА имён (`backend/internal/lang/langpack.go:285`=`"rank-word.txt", "topo-suffix.txt", "grade-prefix.txt", "numeral.txt"`), +у `en` манифест каналов — `none`, и подключение туда сложило бы грамматику глав в версию пакета: правка +грамматики двигала бы крой по чужой денежной оси, а тест остался бы зелёным. ⚠ Системы нужны ДВЕ: римская +(Кристофф) и числительные-слова (`fifty_shades_1_en.txt`: «Chapter Twenty-six», вход ряда 303). -**(а) ДОКУМЕНТ, ИСЧЕРПАННЫЙ СВОИМ ЯРЛЫКОМ, — НЕ ГЛАВА, НО ИМЯ ОН НЕСЁТ.** Это тождество, а не порог: тело, -равное ярлыку, прозы не содержит по построению. **60 из 71.** ⚠ И его имя не выбрасывается — оно -единственное место, где «IV» и «UNFORGIVEN» уже склеены в «Chapter IV. Unforgiven». +**(з) ТРИ МЕСТА «ЮНИТ ОБЯЗАТЕЛЕН» — ПРЕДМЕТ РЯДА 303:** `backend/internal/chunk/ingest.go:366`=`if r != unit {` · +`backend/internal/chunk/ingest.go:290`=`for _, u := range st.UnitOrdered {` · +`backend/internal/chunk/ingest.go:397`=`for _, unit := range st.UnitOrdered {`. Грамматика вида «Chapter One» (маркер + +номер словом, без юнита) книгу не режет, хотя чанкер такой заголовок снять уже умеет. Форма лечения +набросана в дизайне §8.2 (доминанта над формами заголовка, «без юнита» — последним); не ратифицирована — вправе +предложить другую с доводом. -⛔ **ОСТАТОК НАЗВАН ЧИСЛОМ, И ПРЯТАТЬ ЕГО НЕЛЬЗЯ: строгое тождество снимает 60, а ПЯТЬ осколков переживут** — -у них вторая строка несёт имя следующей части. **«Почти-тождество» я запрещаю**: порога не заводить. Решай по -роду — либо правило формулируется так, что ловит и эти пять, либо остаток НАЗЫВАЕТСЯ числом и принимается -осознанно. ⛔ **Пример, который я сюда вписал первым — «каждая строка тела есть ярлык навигации» — ЛОЖЕН, и я -его снимаю: он ловит 0 из 5.** Вторые строки этих осколков («Book Three. To Kill a King») ярлыками не являются -(ярлык — «BOOK THREE»), а пятый осколок несёт вовсе хвост оглавления (`Dawn` · `Acknowledgments` · `Also by` · -`About the Author` · `Copyright`). ⚠ Точное разбиение: ЧЕТЫРЕ осколка со второй строкой-именем следующей части -и ОДИН с хвостом оглавления. Родовой признак ищи сама — или принимай остаток числом. ⛔ Чего нельзя — сдать «сделано» и -получить 89 глав вместо 84. +**(и) `en-ru/heading.txt` НЕ СОЗДАВАТЬ.** Любой шаблон отвечает на вопрос владельца В-1 (`D39.258` п.8: какой +номер главы видит читатель) и включает `ApplyHeading` — ряд 201. Назови строкой отчёта. -**(б) ТАМ, ГДЕ НАВИГАЦИЯ НЕ ПОСТАВИЛА ЦЕЛИ, ГРАНИЦУ СТАВИТ ГРАММАТИКА.** Настоящие начала глав живут внутри -прозы и навигационных якорей не имеют вовсе; сегодня их не видит никто. ⚠ **Формулировать это как «навигация -молчит» — ошибка:** она называет 65 глав поимённо, она лишь целит не туда. +### 4.2 РЕШИ САМА, с одним обязательным ответом: откуда берётся знание о заголовках этой книги -**(в) ИМЯ БЕРЁТСЯ У ТОГО, КТО ЕГО НЕСЁТ.** Грамматика, взятая одна, даст `title_raw = "IV"` — то есть ХУЖЕ -сегодняшнего, потому что имя в прозе стоит СЛЕДУЮЩИМ абзацем. ⇒ **сшивка обязана назвать, откуда каждая из 84 -глав получает имя**, и это входит в приёмку. Вход ряда **284** и §7.1-бис дизайна (title_raw обязан -заполняться любым новым детектором) — читай их до стройки. +⛔ **Книжные данные до книги, идущей через API платформы, сегодня не доезжают.** `book.yaml` такой книги +рендерится один раз из шаблона оператора +(`platform/internal/config/config.go:259`=`BookTemplate is the operator's starting`), платформа вписывает только +идентичность, языки и имя файла, а крой снимается на интейке. Существующий книжный оверлей грамматику тоже не +понесёт — он отказывает любому файлу вне манифеста пары +(`backend/internal/lang/langpack.go:463`=`an overlay merges only the source/pair manifest files`), а лестница +грамматики (`backend/internal/lang/structure.go:142`=`func LoadSourceStructure(root, sourceLang string)`) книжной +ступени не имеет. +⇒ **решение пака обязано работать для книги прогона БЕЗ книжных данных.** Законные источники, по слову +владельца: то, что уже несёт сама книга (тождество, имена навигации, печатное оглавление), и языковые данные +источника (`structure.txt` — данные ЯЗЫКА ИСТОЧНИКА, не пары) — последние только с доказанной инертностью на +корпусе дерева: прогон «до/после» по ВСЕМ исходным книгам `books/`, и где явления нет, число глав не +меняется. Книжная ступень не запрещена, но и не требуется; если строишь — ступенью лестницы со своим +отпечатком (`backend/internal/lang/structure.go:127`=`func structureFingerprint(origin string, b []byte) string`), +не через оверлей и не полем брифа. +**Имя главы на извлечённом тексте:** класса абзаца там нет (обходчик его не отдаёт). Развилка твоя, но выбором +из трёх: (i) канал из обходчика с пином байт-паритета — это снятие запрета (в), только пингом; (ii) признак +имени значением ДАННЫХ грамматики; (iii) имя только от навигации или печатного оглавления. ⛔ Правило «прописные += имя» в Go — ветка по письменности, запрещено. ⚠ Не путать со свёрткой регистра ПРИ СРАВНЕНИИ: это общая +Unicode-операция, она разрешена — и без неё сопоставление ярлыка с прозой даёт 0 из 81 вместо 65. +**Судьбы, которые объявляешь ты, и они входят в приёмочное число N:** `SUNSET` (одна глава или три +безымянных) · `DAWN` (голое числительное приклеит его к главе «Execution») · шесть титулов частей с эпиграфами +(отдельная глава или преамбула главы I). -**(г) ТИТУЛ ЧАСТИ ОБЯЗАН ОСТАТЬСЯ ГРАНИЦЕЙ, И СЕГОДНЯ ЕГО СПАСАЕТ СЛУЧАЙНОСТЬ.** Два титула уцелели лишь -потому, что несут подзаголовок (`BOOK ONE`+`DEATHSEEKER`). **Титул без подзаголовка был бы тождеством**, и -правило (а) сняло бы границу ЦЕЛОЙ ЧАСТИ — молча, при зелёной батарее. Для «пары, которой в репо ещё нет» это -класс, а не частность. ⇒ **пин ровно на эту форму**: тождественный титул, за которым идут документы без -навигационных целей, ⇒ граница СОХРАНЯЕТСЯ. +### 4.3 Докуда имя доезжает — граница, которую пак не переходит -⛔ **ГРАНИЦЫ, КОТОРЫЕ Я СТАВЛЮ ЖЁСТКО:** порога в знаках в Go **не заводить** · список служебных ролей -**не расширять** (узость намеренна: `backend/internal/chunk/epubtoc.go:327`=`func isServiceRole(role string) bool`) · -ветки по паре или языку **не появляется ни одной**. +Имя доедет до манифеста движка. Платформа его не читает (`platform/internal/ingest/manifest.go:124`=`type ManifestChapter struct` +— поля id, номер, юниты, цена), а в книге читателя заголовок берётся из шаблона пары, которого у английской +нет: `backend/internal/pipeline/bookbuild.go:554`=`t := ce.Heading`, при пустом — +`backend/internal/pipeline/bookbuild.go:556`=`t = strconv.Itoa(ce.Chapter)`. Это долг рядов 284 и 201; +назови его строкой отчёта и не чини здесь. -⛔ **И ОДНО, ЧТО ПРОМТ ОБЯЗАН БЫЛ РЕШИТЬ И НЕ РЕШАЛ — ИСХОД ДОКУМЕНТА, НА КОТОРОМ ГЛАВУ НЕ ОТКРЫЛИ.** Прежняя -редакция писала «не потерять ни знака» и тут же требовала переписать докблок -`backend/internal/chunk/epubtoc.go:289`=`NO DOCUMENT IS DROPPED HERE` — это ДВА РАЗНЫХ исхода, и я их склеил. -Замер: группировка приклеивает любой неграничный документ к ПРЕДЫДУЩЕЙ группе, а осколки стоят ПОСЛЕ всей -прозы ⇒ «просто не открывать главу» отправит 65 строк оглавления в хвост последней части, и они будут -переведены и отгружены читателю — та же трата, что в ряду **283**, только в другой главе. -⇒ **РОВНО ТАК: документ-тождество ИСКЛЮЧАЕТСЯ из чтения, а не приклеивается**, с названной причиной и -размером; инвариант сохранения получает это третье состояние; докблок переписывается тем же движением и -называет условие, при котором вывод держится. ⚠ Судьбу документа, у которого нет навигационной цели и который -сегодня приклеивается к последней части, назови отдельной строкой отчёта. +### 4.4 ЗАМЕР ПЕРЕД СТРОЙКОЙ — ПЕРВЫМ ДЕЛОМ, БЕЗ ЕДИНОЙ СТРОКИ Go -**РОВНО ТАК по видимости:** рядом с существующими счётчиками аномалий (`unresolved`, `collapsed`, `attached`) -появляется свой, и число доезжает до человека. +Реализуй правило на python и прогони по книге прогона и по корпусу. Ответь числами: сколько границ даёт +объединение (б) · сколько глав получили имя и откуда · сколько безымянных · N против печатного оглавления и +против 71 записи навигации · сколько ложных срабатываний на корпусе. ⚠ Кандидаты, ложные для приоров имени (замер круга, пере-сними): +абзацы `044…047` по одному слову прописными (`SHARP.` `AS.` `THREE.` `SWORDS.` — стилизованная фраза по +странице) и подпись эпиграфа в `015` (`—LUIS BETTENCOURT`) — тот же класс абзаца, всё прописными, и ни одно +не имя главы; у трёх номеров `SUNSET` следом идёт проза. ⇒ **приёмочное число N объявляешь ты** +вместе с судьбами §4.2, и оно входит в записку-план числом. -### 4.2 ГРАММАТИКА КОНКРЕТНОЙ КНИГИ ПРИЕЗЖАЕТ ЕЁ ДАННЫМИ +### 4.5 ЧТО ПАК СДВИНЕТ В ДЕНЬГАХ -Сегодня грамматика читается **только** из пар-данных языка -(`backend/internal/lang/structure.go:142`=`func LoadSourceStructure(root, sourceLang string)`), лестница из -трёх ступеней, книжной ступени нет. А грамматика заголовков КОНКРЕТНОГО файла есть свойство **конверсии -издателя**, то есть книги, а не письменности: тот же роман у другого издателя размечен иначе. +Правка правила ингеста бампает версию нарезки — конвенция самого кода: +`backend/internal/pipeline/manifest.go:355`=`treats an ingest-rule change as a chunkerVersion bump`. Версия +сворачивается в ключ манифеста (`backend/internal/pipeline/manifest.go:383`=`Chunker: chunkerVersion`, рядом +`backend/internal/pipeline/manifest.go:385`=`Structure: r.structure.Fingerprint()`) и в снапшот +(`backend/internal/pipeline/snapshot.go:463`=`ChunkerVersion: chunkerVersion`). ⇒ **ключ манифеста КИТАЙСКОЙ +книги сдвинется** — через версию нарезки, а не через отпечаток (у неё отпечаток CJK-грамматики, пустой +`-none` — английский свидетель). §4.1-бис ниже вдобавок меняет ТЕКСТ чанка. +Сегодня это бесплатно при названном условии: ни одну существующую базу с оплаченными чанками никто не +продолжает (корпус одноразовый — `D39.63` (3), `D39.190` п.4). Продуктовый путь на этом хосте не проверен +(`TM_PLATFORM_BOOKS_DIR` не задан ⇒ «не нашёл», а не «проверил»). Пак лендится ДО фриза прогона; промт +прогона переписывает оркестратор. **Тебе — строкой отчёта: что сдвинулось, у каких книг, какой пере-снапшот.** -⛔ **И вот здесь я ошибся, проверь сама и не повтори за мной.** Я написал было «дом уже ратифицирован — -книжный оверлей» (`backend/internal/config/book.go:105`=`LangpackExtend string`, -`backend/internal/lang/langpack.go:413`=`func LoadWithOverlay(root, src, tgt, overlayRoot string)`). **Это -переоценка: существующий оверлей такой файл ОТКАЖЕТ.** Он сливает только файлы манифеста, и его собственная -ошибка это говорит — `backend/internal/lang/langpack.go:463`=`an overlay merges only the source/pair manifest files`; -`structure.txt` не входит ни в `backend/internal/lang/langpack.go:283`=`var srcFiles = []string{`, ни в -`backend/internal/lang/langpack.go:290`=`var pairFiles = []string{"palladius.txt"`. Ратифицирован он для -частного канона, не для грамматики. +### 4.1-бис Ряд 346 (б): правило заголовка разъехалось по двум предикатам — сведи в одно -**РОВНО ТАК по дому:** книжная ступень у ЛЕСТНИЦЫ ГРАММАТИКИ -(`backend/internal/lang/structure.go:142`=`func LoadSourceStructure(root, sourceLang string)` — сегодня три -ступени, книжной нет), со СВОИМ отпечатком через -`backend/internal/lang/structure.go:127`=`func structureFingerprint(origin string, b []byte) string`. **НЕ через -`LoadWithOverlay` и НЕ полем брифа.** Довод денежный: поле брифа уходит в хеш брифа, -оттуда в КАЖДЫЙ хеш запроса, и вдобавок рендерится модели. Грамматике границ ехать туда незачем — ей место в -КРОЕ, а крой уже фолдит отпечаток структуры. +Страж длины живёт только в ингесте (`backend/internal/chunk/ingest.go:341`=`const chapterHeaderMaxRunes = 60`), +осмысленность номера — только в чанкере (`backend/internal/chunk/chunker.go:315`=`v := section + num`). На +заголовке С сепаратором после юнита длиной 61–84 руны ингест говорит «нет», чанкер «да»; `第零章` ингест режет, +а чанкер заголовок не снимает — сырой маркер уезжает модели. Без сепаратора расхождения нет. Направление +названо в самом ряду: сведение двух предикатов к ингестовским стражам. Пин +`backend/internal/chunk/headingparity_test.go:106`=`THE FIX IS NOT IN SCOPE HERE AND IT IS NOT $0` краснеет +ровно при фиксе — **ты тот фиксер**: переворачиваешь его вместе с правилом и объявляешь как заказанную смену +поведения. ⚠ У пина расхождения записи в каталоге мутаций нет — заведи посадку под новое правило и введи в гейт. +В китайском корпусе `第零章` — 0 и заголовков длиннее 60 рун — 0; скажи это числом в отчёте. -**РЕШИ САМА,** что грамматика обязана уметь для этой книги. Приоры, каждый опровергается замером: -безмаркерный заголовок (сегодня маркер требуется) · класс римских числительных (сегодня арабские и CJK) · «абзац, чей текст есть голое числительное» · -«имя главы — СЛЕДУЮЩИЙ абзац того же класса». +### 4.6 Чего пак не делает -⛔ **Приор «центрированный абзац» я СНИМАЮ, и вот почему — иначе он столкнул бы тебя лбом с §4.5.** -Вычисленный стиль виден только внутри обходчика `backend/internal/chunk/ingest.go:1155`=`func extractXHTML`, а -§4.5 запрещает его трогать: там четыре пина байт-паритета и ошибка ТИХАЯ. Наружу сегодня выходит курсив — -глифом, — а канала «центрирован» нет вовсе. ⇒ либо обойдись без стиля (замерь, даёт ли «абзац = голое римское -числительное» ровно 84 на ЧИСТОМ тексте и сколько даёт ложных), либо **приходи с доводом и ПИНОМ**, а не -правь обходчик молча. ⚠ Мой приор был внутренне противоречив; это моя ошибка, не твоя развилка. - -### 4.2-бис ⛔ ПРАВИЛО ЗАГОЛОВКА УЖЕ ПРОТИВОРЕЧИТ САМО СЕБЕ — ряд **346** половина (б), и ты встанешь ровно на него - -**Найдено оркестратором 18.09 чтением бэклога, в пак внесено намеренно.** Ты собираешься заставить грамматику -участвовать там, где режут. Но правило «что такое заголовок» **сегодня разъехалось по двум предикатам, и они -дают РАЗНЫЕ ответы на одном входе**. Строить поверх противоречия — значит закрепить его в третьем месте. - -**Замер, уже снятый и пере-снятый на копии дерева (ряд 346, повторишь своим прибором):** -- Страж ДЛИНЫ живёт только в ингесте — `backend/internal/chunk/ingest.go:341`=`const chapterHeaderMaxRunes = 60`; - в чанкере длина не проверяется вовсе. -- Осмысленность НОМЕРА живёт только в чанкере — `backend/internal/chunk/chunker.go:315`=`v := section + num`. -- ⇒ на заголовке С СЕПАРАТОРОМ после юнита (`第四章:…`) длиной 61–84 руны ингест говорит `false`, чанкер — - `ok=true`. ⚠ **Без сепаратора расхождения НЕТ** ни на одной длине, и без этой оговорки строка читается как - ложная: такую строку отвергают оба предиката. -- Отдельно: `第零章` (пролог нулевой главой) ингест режет главой, а чанкер заголовок НЕ снимает ⇒ `heading=""`, - и сырой CJK-маркер уезжает МОДЕЛИ. - -**Половина (а) уже закрыта** актом `D39.225`: пин расхождения и паритет-тест стоят, оба под мутациями. Пин -написан так, что **краснеет ровно тогда, когда приземлится фикс** — это сделано намеренно, чтобы фиксер не смог -починить молча. ⇒ **ты — тот фиксер, и покрасневший пин здесь НЕ «протухший тест», а приглашение**; правишь его -вместе с правилом и объявляешь это в отчёте по норме «правка, вызванная заказанной сменой поведения». - -⛔ **И вот зачем это в ЭТОМ паке, а не отдельным:** предмет один — «чем определяется, что строка есть заголовок -главы». Пока он живёт в двух предикатах, «подключить грамматику к EPUB» означает выбрать, к КОТОРОМУ из двух -подключаться, и любой выбор молча объявит второй неправым. ⇒ **сведи правило в ОДНО место и позови оттуда -всех троих** — ингест текстовый, ингест EPUB, чанкер. Это и есть «чистый архитектурный код» в формулировке -владельца, а не рефактор ради рефактора. - -⚠ **Ряд 346 пере-проверь сама:** его прошлая редакция уже была однажды исправлена как ложная, и оговорка про -сепаратор — след той правки. - -### 4.3 ЧТО ПРОИСХОДИТ, КОГДА ПОЛИТИКА НЕ ОБЪЯВЛЕНА: ПРОХОД С НАЗВАННОЙ АНОМАЛИЕЙ - -**РОВНО ТАК, и довод взят из самой кодовой базы:** `backend/internal/pipeline/runner.go:389`=`merely costs money it did not mean to spend` — конфигурация, -которая верна и лишь стоит денег, которых не собиралась тратить, есть форма, о которой этот код -**ПРЕДУПРЕЖДАЕТ, а не отказывает**; отказы — для механизма, который не может работать вовсе. Кривое -оглавление — первое, а не второе. - -⚠ **Оговорка, без которой абзац лжёт:** правило (а) живёт в Go и действует на КАЖДЫЙ EPUB с осколками-тождествами, -объявлена грамматика или нет. Без грамматики отсутствует только (б). -⇒ человек видит числом, что получил: сколько глав, -сколько из них несут прозу, какова медиана и самая длинная, сколько фрагментов оглавления опознано -тождеством. Одной строкой в человеческой сводке и теми же числами в машинной. - -⚠ **Почему не отказ:** большинство реальных EPUB собраны такими же конвертерами. Отказ на «оглавление -выглядит странно» сделал бы движок капризным к массовой форме входа и заставил бы объявлять грамматику для -каждой книги. Это не «приличная мультиязычность», а её противоположность. - -### 4.4 ⛔ ЗАМЕР ПЕРЕД СТРОЙКОЙ — ПЕРВЫМ ДЕЛОМ, И БЕЗ ЕДИНОЙ СТРОКИ Go - -Прежде чем править код, **реализуй правило грамматики на python и прогони по книге прогона**. ⚠ **Прежняя -редакция этого абзаца протухла** — она звала «центрированный короткий абзац», а §4.2 приор «центрирован» снял, -и звала сверяться «против записей навигации», которых у прозы нет. - -**Правило меряй на ИЗВЛЕЧЁННОМ тексте, а не на разметке:** «абзац, чей текст есть голое римское числительное; -имя главы — следующая непустая строка того же класса». ⚠ Оговорка из замера: у 53 пар абзацы идут подряд, у 28 -между ними пустой абзац-спейсер; на извлечённом тексте он исчезает, в разметке «подряд» неверно. - -**Ответь числами:** сколько глав даёт правило · сколько из них получили имя · сколько осталось безымянных · -чему это равно против собственного оглавления книги (81 + Sunset) и против 71 записи навигации. -⇒ **приёмочное число — то, которое ты назовёшь, объявив судьбу пролога;** мои ориентиры — 84 по прибору и -82 по оглавлению книги, и расходятся они ровно на неё. Если правило даёт число, не похожее на настоящую структуру книги, — -стройка начинается не с того, и лучше это узнать за ноль долларов и без правок дерева. Так же вчера был -пере-снят механизм группировки, и это сэкономило пак. - -### 4.4-бис ⛔ ЧТО ЭТОТ ПАК СДВИНЕТ В ДЕНЬГАХ — сказано ЗАРАНЕЕ, потому что узнать это после лендинга дорого - -**Правка правила ингеста двигает ключ манифеста, и не только у английской книги.** Конвенция записана в самом -коде: `backend/internal/pipeline/manifest.go:355`=`treats an ingest-rule change as a chunkerVersion bump`. -А в ключ сворачиваются оба — `backend/internal/pipeline/manifest.go:281`=`Chunker: chunkerVersion` и -`backend/internal/pipeline/manifest.go:283`=`Structure: r.structure.Fingerprint()`, причём отпечаток несёт -версию алгоритма ДАЖЕ у пустой грамматики (`backend/internal/lang/structure.go:104`=`structureAlgoVersion + "-none"`). -⇒ **ключ манифеста КИТАЙСКОЙ книги сдвинется тоже.** Вдобавок §4.2-бис меняет ТЕКСТ чанка. - -⛔ **И потому: акт `D39.269` п. B1 утверждал «китайская половина неподвижна» — это было верно про ПРЕДЫДУЩИЙ -пак и перестаёт быть верным про твой.** Не «обходи», а **НАЗОВИ**: в отчёте отдельной строкой — что сдвинулось, -у каких книг, и какой пере-снапшот это требует. Эррату к акту пишет оркестратор, не ты. -⚠ **И ещё одно следствие, за пределы твоей зоны:** пак холодного прогона -(`docs/COLDRUN_TWO_BOOKS_SESSION_PROMPT.md`) несёт ПРЕ-РЕГИСТРИРОВАННЫЕ числа среза английской книги и -стоп-правило «срез не совпал с пре-регистрированным → СТОП». После тебя крой другой, и те числа протухают. -**Твой пак лендится ДО фриза прогона**; пере-регистрацию делает пак прогона. Тебе — только строка в отчёте. - -### 4.5 ЧТО В ЭТОТ ПАК НЕ ВХОДИТ — чтобы ты не расширяла его по своей инициативе - -**Ряд 302** (несколько глав в ОДНОМ документе, разделённых якорями, схлопываются в одну) — **противоположный** -предмет, и дизайн вынес его из окна с названной ценой: единственное место, трогающее байтовый путь -извлечения, где ошибка ТИХАЯ. Не трогай. -**Ряд 201** (движковое «Глава N» доезжает читателю внутри текста) и **284** (название книги и заголовки -через термины) — соседние предметы того же дизайна; в этот пак не входят. Увидишь, что твоя правка их -задевает, — скажи, не чини. -**Большой перекрой** из дизайна (адресация главы контентом, четыре таблицы по ординалу) — **НЕ этот пак**. -Его механика в четырёх кругах не сошлась, и заходить в неё сейчас значит открыть предмет, который мы не -закроем до прогона. +Большой перекрой (ряд 161, дизайн §9, миграции) · ряд 302 в форме якорей навигации · правку обходчика +`extractXHTML` · правки платформы (чужая зона; что ей нужно — строкой отчёта) · `en-ru/heading.txt` · провод +счётчиков к пользователю (носитель — ноты ингеста, дальше не тянуть). --- -## 5. Самопроверка исполнением — и где у ЭТОГО пака мягко +## 5. Самопроверка исполнением — и четыре места, где этот пак мягок -Ревью исполнением обязательно: своего кода, своих проб, своих результатов. **Субагенты разрешены.** -**Fable 5 — ОДИН советчик** с постоянным контекстом; он советчик, а не источник истины. +Ревью исполнением: своего кода, своих проб, своих чисел. **Субагенты и воркфлоу разрешены.** Советчики — +**до двух фаблов** (`model: "fable"` явно) с ПОСТОЯННЫМ контекстом; советоваться на ПРОЕКТИРОВАНИИ и на ПРИЁМКЕ; +спрашивать: сомнение · развилка · не построено ли уже · не противоречит ли ратифицированному. Советчик — не +источник истины, его посылки проверяются деревом. Внутри воркфлоу тот же потолок. **Механизм обязателен:** +интервальная самоверификация субагентом против списка §13 — по готовности каждого из (а)–(з) и перед сдачей. -**СЕМЬ МЕСТ, ГДЕ ЭТОТ ПАК МЯГОК ИМЕННО ПОТОМУ, ЧТО ОН ТАКОЙ:** +1. ⛔ **Верный ответ неверным методом.** Число глав сойдётся построчной машиной на английской паре — через + курсив пары. Проверяй метод, а не число: `ingest(p)` с разметкой `nil`, абзац, а не строка. +2. ⛔ **Резка внутри документа и ruby.** Контрольный набор устроен 1:1 и эту форму не ловит. Синтетический + CJK-EPUB: две главы в одном документе, ruby во второй — пин на номер главы у чтения. ⚠ **Ожидаемый исход + назван заранее:** обходчик отдаёт ruby без позиции, поэтому пин без его правки невыполним — итог либо пинг + (правка обходчика снимает запрет (в)), либо атрибуция по документу, объявленная ограничением в отчёте. + Третьего исхода — эвристики «найти базу ruby по тексту главы» — промт не санкционирует. +3. ⛔ **Исключение как пропуск — и пины, которые зелены без правила.** Оба пина (г) и «PART ONE» ОТРИЦАТЕЛЬНЫЕ: + они проходят и при полном отсутствии правила (а), а на книге 1:1 правило не срабатывает вовсе. ⇒ обязателен + ДИФФЕРЕНЦИАЛЬНЫЙ синтетический пин: осколок-тождество, чей ярлык сопоставлен заголовку в прозе ⇒ исключён с + ролью, глав на одну меньше; ТОТ ЖЕ осколок, чей ярлык прозе не сопоставлен ⇒ остаётся. Без второй половины + условие «сопоставлен» не стережёт ничего. Условие исключения — в докблоке. +4. ⛔ **Грамматика этой книги под видом грамматики языка.** Всё, что выведено из Кристоффа, меряется на корпусе: + `books/fifty_shades_1_en.epub` (NCX 34 цели 1:1 — правило (а) обязано не сработать ни разу), + `books/isekai_majutsushi_jp.epub` (44 цели; сегодня грамматики на EPUB-пути не получает, после пака получит — + 44 до и 44 после), `books/fifty_shades_1_en.txt` (52 строки «Chapter…», номера словами, цифр 0 — вход ряда + 303). Пин не строится на той же фикстуре, из которой выведено правило; образец правильного шва — + `backend/internal/chunk/epubtoc_test.go:428`=`func TestANewLanguageCutsFromItsDataFileAlone`. -1. ⛔ **Твоя правка меняет КРОЙ, а крой versionируется.** По конвенции проекта правка правила нарезки - бампает версию нарезки, а та фолдится БЕЗУСЛОВНО — то есть у КАЖДОЙ книги, включая китайскую. - **Сегодня это бесплатно, но условно, и условие я называю словами:** бесплатно ⇔ ни одну существующую базу - с оплаченными чанками никто не ПРОДОЛЖАЕТ. Замер: в `coldrun-a` 20 строк `chunk_status` на $0.024056, в - `coldrun-b` — 0; всех баз с оплаченными строками под `books/` — 161, и все объявлены одноразовыми - (`D39.63` п.3, `D39.190` п.4). ⚠ **Продуктовый путь на этом хосте НЕ проверен:** `TM_PLATFORM_BOOKS_DIR` - не задан, каталогов-кандидатов нет — то есть здесь «нет» значит «не нашёл», а не «проверил». - Предстоящий прогон стартует ПОСЛЕ лендинга ⇒ куплено ничего. Предъяви цену явно, не умолчи её. -2. ⛔ **Тождество легко сделать почти-тождеством, и тогда оно станет порогом.** «Равно ярлыку» и «начинается - с ярлыка плюс немного» — разные правила: первое доказуемо, второе — эвристика с невидимой границей. - Замер (пере-снят вторым кругом, прежняя редакция говорила «одно почти-тождество» и была неверна): - **60 тождеств и СЕМЬ коротких не-тождеств** — два титула частей и пять осколков. Если возьмёшь «почти», - скажи, где теперь граница и чем она обоснована. ⛔ Я её брать запрещаю; см. §4.1(а). -3. ⛔ **Грамматика, которая режет ЭТУ книгу, легко окажется грамматикой этой книги.** Признак «абзац есть - голое числительное, имя — следующая непустая строка» обязан быть выведен из свойства ВЁРСТКИ, а не подобран - под Кристоффа. ⚠ Прежняя редакция звала «римскую цифру в центрированном абзаце» — приор снят в §4.2. - ⛔ **Контрольный набор я назвал неверно, и неверно он звучал правдоподобно:** «китайская книга» — это TXT - (`books/gu-zhenren`), и EPUB-пути она не касается вовсе. **Настоящий контроль — два EPUB дерева:** - `books/isekai_majutsushi_jp.epub` (CJK-EPUB, получает умолчательную грамматику на EPUB-пути) и - `books/fifty_shades_1_en.epub` (латиница, цели навигации 1:1 с документами — отрицательный контроль: - правило (а) обязано на нём не сработать ни разу). Китайская книга — контроль только на сдвиг версии. -4. ⛔⛔ **ИМЯ, КОТОРОЕ ТЫ СБЕРЕЖЁШЬ, ДО КНИГИ ЧИТАТЕЛЯ СЕГОДНЯ НЕ ДОЕЗЖАЕТ — и §4.1(в) без этой оговорки - обещает больше, чем даёт.** Замер: в билдере выдачи `TitleRaw` — **0 вхождений** - (`backend/internal/pipeline/bookbuild.go`, контроль: в дереве он живёт в трёх файлах — `epubtoc.go`, - `ingest.go`, `manifest.go`), а заголовок главы в файле берётся из - `backend/internal/pipeline/bookbuild.go:554`=`t := ce.Heading`, то есть из шаблона пары, которого у `en-ru` - нет. ⇒ имя доедет до МАНИФЕСТА и до платформы, а в книге читателя главы останутся номерами. - **Это не повод не сберегать имя** — это повод НАЗВАТЬ границу: скажи в отчёте, докуда имя доезжает и где - остаётся долгом (ряды **284** и **201**). ⛔ И отдельно сверься с `D39.205` («без пропусков», слово - владельца): исключение документа-тождества не есть потеря текста книги — тело равно ярлыку, — но написать - это обязана ты, а не читатель твоего отчёта. -5. ⛔ **Каталог мутаций придётся пере-нацелить, и это часть пака, а не побочная уборка.** Перестройка - группировки уводит цель у посадки на `NO DOCUMENT IS DROPPED`, а «имя у носителя» — у посадки на источник - `title_raw`. **Посадка, потерявшая цель, даёт НЕИЗМЕРЕННУЮ, а не пойманную**, и неизмеренная, прочитанная - как пойманная, хуже выжившей. Пере-нацель и скажи, сколько записей тронуто. -6. ⛔ **Край платформы: отказ интейка `400 no_chapter_structure` при `ChaptersTotal < 2`.** EPUB из двух - документов, один из которых тождество, даст одну главу — и книга не пройдёт дверь. Поставь пин на этот край. -7. ⛔ **Пин на новую грамматику легко построить на той же фикстуре, из которой она выведена.** Тогда он - докажет, что правило работает на том, из чего сделано. Образец правильной формы в дереве есть — пин, - который режет книгу ИЗ ОДНОГО ФАЙЛА ДАННЫХ и падает без него. +**Мутации — часть пака.** В каталоге `backend/cmd/tmmutate/mutations.json` 557 записей, в гейте 346 +(`backend/Makefile:116`=`run ./cmd/tmmutate -root`). Предмету принадлежат **12 записей ВНЕ гейта:** +`EPUB-preamble-joins-chapter-one` · `EPUB-conservation-no-document-leaves-unaccounted` · +`EPUB-unresolved-counts-only-what-it-promises` · `EPUB-service-pages-are-exactly-two-roles` · +`TITLE-raw-epub-half-comes-from-the-label` · `PP-structure-provenance` · `DF-competition-order-loses-a-chapter` · +`EPUB-collapsed-targets-downgrade-the-provenance` · `EPUB-service-role-at-a-point-keeps-the-document` · +`INGEST-every-count-reaches-the-operator` · `MANIFEST-key-carries-the-structure-grammar` · +`TITLE-raw-follows-the-kept-index`. Потерянный якорь покраснеет сам (проверка гниения каталога идёт по всему +каталогу), но ловит ли тест посадку, которая всё ещё сажается, — вне гейта не меряет никто. ⇒ прогони их +поимённо через `-id` на копии; введи в гейт или скажи, почему нет. Популяция таблицы = гейт + эти 12 + новые. --- -## 6. Оси ревью +## 6. Оси ревью (вправе заменить с аргументом) -- **Код:** батарея + живые пробы + СВОИ адверсариальные посадки вне твоего списка. Пак, меняющий крой, - принимается прогоном через настоящий драйвер, а не чтением диффа. -- **Данные:** каждое значение грамматики — с доводом, из какого свойства вёрстки выведено. -- **Швы:** отпечаток структуры едет в крой; проверь, что он двигается ровно тогда, когда должен. +- **Код и швы:** батарея + живые пробы + свои посадки вне списка; крой принимается прогоном через настоящий + драйвер ингеста, а не чтением диффа. +- **Общность:** для каждого правила — «заработает ли книга без явления без правки Go» числом на корпусе. +- **Провенанс и деньги:** метка нарезки и ключ манифеста двигаются ровно тогда, когда должны. -**Кодовому паку дополнительно:** пин на УСЛОВНОЕ сообщение обязан иметь фикстуру, где оно ОБЯЗАНО -прозвучать · перед отчётом сверь каждый клейм с результатом инструмента ЭТОЙ сессии · последний абзац -отчёта оказался планом — сделай сейчас · **править тесты ради зелени недопустимо**, но правка, вызванная -ЗАКАЗАННОЙ сменой поведения, есть обслуживание и ОБЪЯВЛЯЕТСЯ · дифф `^func Test` предъявляй исполнением. +**Кодовому паку дополнительно:** пин на УСЛОВНОЕ сообщение обязан иметь фикстуру, где оно ОБЯЗАНО прозвучать · +перед отчётом сверь каждый клейм с результатом инструмента ЭТОЙ сессии · последний абзац отчёта оказался +планом — сделай сейчас · **править или удалять тесты ради зелени недопустимо**; правка, вызванная ЗАКАЗАННОЙ +сменой поведения, — обслуживание и ОБЪЯВЛЯЕТСЯ · дифф `^func Test` предъявляй исполнением · комментарий, +несущий вывод, называет условие, при котором вывод перестаёт держаться; прозы и гарантий без пина в коде нет. --- ## 7. Записка-план -До первой правки кода — записка: что делаешь, в каком порядке, что считаешь спорным. ⚠ Замер §4.4 идёт -ПЕРВЫМ и входит в записку числом, а не обещанием. +До первой правки кода: замысел (проектирование раньше кода) · порядок · что спорно · N из §4.4 числом · +комплектность против заказа — таблица «пункт §4 → как будет сделан». Советчик смотрит записку до стройки. --- ## 8. Заявление есть команда -Каждое число — с командой. У каждого НУЛЯ печатается контрольная величина. -**Ловушки среды:** обёртка `grep` чтит игнор-файлы и не видит `books/` — бери `command grep` · `find` здесь -**bfs**: относительное время только `-mmin`, и он тоже чтит игнор-файлы · командной утилиты для баз нет · -⚠ **знаки и байты — разные популяции**, «текст файла» и «текст тела» — тоже: на этом я сегодня получил ноль -тождеств там, где их шестьдесят. +Каждое число — с командой повторения. У каждого НУЛЯ печатается контрольная величина. Эрудиция — не улика: +утверждение грунтуется `file:line` или замером, иначе помечается «мнение». +**Ловушки среды (каждая даёт тихий ложный ноль):** обёртка `grep` чтит игнор-файлы и не видит `books/` — бери +`command grep`; `books/` — симлинк, и `find` без `-L` в него не заходит; `find` здесь bfs (относительное время +только `-mmin`); CLI для баз нет; знаки и байты — разные популяции. --- ## 9. Эхо старта -До работы — ≤10 строк **СВОИМИ словами**: скоуп · инварианты · чего не делаешь. Шли первым действием. +Первым действием — ≤10 строк **СВОИМИ словами** (дословный пересказ подтверждает канал, но не понимание): +скоуп · инварианты · чего не делаешь. Шлёшь оркестратору по адресу из канала (§12) — это и проверка канала. --- ## 10. Что НЕ удалось и где прибор слеп -Обязательная секция, две половины: «что не получилось» и **«что ты знаешь и не сказала»** — что невидимо · -почему не чинила · чем закрывается. +Обязательная секция отчёта, две половины: «что не получилось» и **«что ты знаешь и не сказала»** — что +невидимо · почему не чинила · чем закрывается. В коде названо, в отчёте нет — значит для следующей смены не +названо. --- ## 11. Канал вопросов и право отказаться -Конфликт промта с деревом — **пинг, а не интерпретация**. Право сказать «этого делать не надо» с аргументом -есть и поощряется. -⚠ Этот промт написан после того, как я **сам ошибся в постановке дважды**: сперва обошёл предмет срезом, -потом склеил два факта в один. Оба раза поправил замер, а не рассуждение. Найдёшь третью — говори. +Конфликт промта с деревом или с журналом решений — **пинг, а не интерпретация**: оркестратору через канал, а +нет канала — секцией отчёта, владелец пере-передаст. Право сказать «этого делать не надо» с аргументом есть и +поощряется. Дополнения к паку в ходе работы приходят ТОЛЬКО релеем владельца; приём эхо-подтверждается и +идёт отдельным пунктом отчёта. --- ## 12. Прямой канал -`/tmp/textmachine-channel` — впиши свой блок первым делом. ⚠ Адрес из файла не доказывает, что сессия жива: -сверься с `ListAgents`. +Механизм — `CLAUDE.md`, раздел «Связь между сессиями». Файл — `/tmp/textmachine-channel`: впиши свой блок +первым делом, адрес оркестратора возьми оттуда и сверь с `ListAgents` — адрес из файла не доказывает, что +сессия жива. **Канала нет ⇒ НЕ искать**: вопрос — секцией отчёта, работа продолжается. --- ## 13. Когда пак считается завершённым -- [ ] Замер §4.4 предъявлен ЧИСЛОМ до первой правки Go. +- [ ] Замер §4.4 предъявлен числом до первой правки Go; N и судьбы `SUNSET` · `DAWN` · титулов частей · + 7 не-тождеств · `058`/`124` объявлены с доводом. - [ ] У каждого пункта §4 — исход: сделано · не делаю с доводом · пинг. -- [ ] **Английская книга режется по своим настоящим главам — числом, которое ты объявила в §4.4** (81 + пролог; - расхождение с прибором названо), и это предъявлено прогоном, а не рассуждением. -- [ ] **Китайская книга не изменилась ПО ТЕКСТУ** — предъявлено побайтным равенством текстов глав и чанков. - ⚠ Её КЛЮЧ МАНИФЕСТА при этом сдвинется, и это ожидаемо — см. §4.4-бис; путать два утверждения нельзя. -- [ ] Ни одной ветки по языку или паре не добавлено — предъявлено грепом с контрольной величиной. -- [ ] Круги СОШЛИСЬ; прежние находки закрыты таблицей «находка → что сделано → **чем предъявлено**». -- [ ] Таблица мутаций полная, ТРИ исхода: поймано · выжило · **НЕ ИЗМЕРЕНО**; новые записи введены в гейт. -- [ ] Числа сняты ПОСЛЕ последней правки; гейт прогнан целиком; рядом с `ok` напечатан счёт скипов. +- [ ] Английская книга режется на N глав — прогоном настоящего драйвера; у каждой главы назван источник имени. +- [ ] Контроли: isekai 44/44 · `fifty_shades_1_en.epub` — (а) сработало 0 раз · 12 номеров в документах с целью + разрезаны · корпус «до/после» по всем исходным книгам `books/` — таблицей. +- [ ] Ряд 303: безъюнитная грамматика режет `fifty_shades_1_en.txt` одним файлом данных (строки с отступом и + CRLF, номера СЛОВАМИ — вторая система счисления, §4.1(ж)) — или ряд назван открытым с доводом; оба исхода + штатные. +- [ ] Китайская книга не изменилась ПО ТЕКСТУ — побайтным равенством текстов глав и чанков; сдвиг её КЛЮЧА + манифеста назван отдельно (§4.5). +- [ ] Ни одной ветки по языку, паре или письменности в Go — грепом с контрольной величиной. +- [ ] Таблица мутаций: гейт + 12 + новые, ТРИ исхода — поймано · выжило · **НЕ ИЗМЕРЕНО**; вердикт по тексту + падения, а не по цвету. +- [ ] Круги СОШЛИСЬ: последний не дал новых находок; прежние закрыты таблицей «находка → что сделано → чем + предъявлено». +- [ ] Список «что отрефакторено и почему» — или «не потребовалось» с доводом; стандарт и аддендум `D39.258` + п.3/п.9 — отдельным пунктом. +- [ ] Числа сняты ПОСЛЕ последней правки; гейт зоны прогнан целиком, полнота — сверкой СПИСКА пакетов; всё + живое — в дереве. - [ ] Явное **«работа завершена, править не планирую»**. -⛔ **И последнее.** Предмет пака — **кто решает, где начинается глава**. Ответ, к которому надо прийти: -тождество решает движок, потому что это факт, а не догадка; АДРЕС границы решает грамматика книги; ИМЯ берётся -у того, кто его несёт. Всё, что сверх этого, решают данные книги. Если твоё -решение где-то ставит догадку движка на место данных — оно не готово, сколько бы тестов ни было зелёными. +⛔ **Ответ, к которому пак ведёт:** тождество, СОПОСТАВЛЕННОЕ заголовку в прозе, решает движок, потому что это +факт книги, а не порог; АДРЕС границы даёт грамматика, +ИМЯ — тот, кто его несёт; всё, что сверх этого, — данные, которые ведут себя верно там, где явления нет. Решение, +ставящее догадку движка на место факта книги, не готово, сколько бы тестов ни было зелёными. diff --git a/docs/BACKLOG.md b/docs/BACKLOG.md index 07c8f74a..bd5bbd11 100644 --- a/docs/BACKLOG.md +++ b/docs/BACKLOG.md @@ -215,7 +215,7 @@ | 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 закрыта и снята). ⛔ **ПЛАТФОРМЕННАЯ ПОЛОВИНА ИСПОЛНЕНА (пере-снято 06.09 по коду, не по комментарию):** число берётся из манифеста движка — `platform/internal/httpapi/project.go:39`=`out.CharacterCountExact` (⚠ испр. 17.09: было :38), рядом с ним флаг точности в `platform/internal/httpapi/v0.go:216`=`CharacterCountExact bool` (⚠ испр. 17.09: было :211), пин `v0_test.go:933`. Остаток строки — ТОЛЬКО подпись `'about.characters': 'Знаков'` во фронте, а зона фронта ЗАМОРОЖЕНА ⇒ строка ждёт разморозки и в платформенные паки больше не входит | фронт | скоро (первое касание при разморозке) | снять ложную подпись `'about.characters'` во фронте (источник уже манифест движка — половина исполнена) | согласование 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 ⭐ **ЧИСЛА НА БОЕВОЙ АНГЛИЙСКОЙ КНИГЕ, замер зоны 18.09 — предмет ряда впервые получил величину.** Книга Кристоффа режется движком на **71 «главу», из которых настоящих ШЕСТЬ** (`BOOK ONE`…`BOOK SIX`, 140–390 тыс. знаков), одна средняя и **64 КРОШЕЧНЫЕ — это страница «Contents», разрезанная конвертером на файлы по одной строке**; детерминированный заголовок непуст у **0 из 71**. Проекция цены всей книги $6.65, из них на 64 осколка **$0.38**. ⇒ ряд перестал быть теоретическим: не-CJK книга платит за оглавление как за главы. ⚠ Механизм группировки документов в коде ЕСТЬ (`backend/internal/chunk/epubtoc.go:293`=`func groupChapters`, привязывает неграничный документ к предыдущей главе) — значит вопрос не «построить», а «почему 64 осколка прошли как границы»; это и есть предмет замера перед стройкой. | бэкенд | скоро (ДО открытия беты не-CJK и EPUB-входам) | этап 1 research/27 своим паком | согласование 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 ⭐ **ЧИСЛА НА БОЕВОЙ АНГЛИЙСКОЙ КНИГЕ, замер зоны 18.09 — предмет ряда впервые получил величину.** Книга Кристоффа режется движком на **71 «главу»**. ⚠ **ИСПР. 18.09 (`D39.270`): прежняя редакция писала «настоящих ШЕСТЬ, 64 крошечные» — это граница ДОКУМЕНТОВ, а не глав.** Настоящих глав по печатному оглавлению книги **81** плюс разделы `SUNSET` и `DAWN`; навигация называет 65 из них и целит в осколки оглавления (60 тел побуквенно равны ярлыку), 28 прозаических документов несут по 2–7 глав. Полная раскладка — таблица §1 промта `docs/BACKEND_CHAPTER_STRUCTURE_SESSION_PROMPT.md`. Прежние слова: «настоящих ШЕСТЬ (`BOOK ONE`…`BOOK SIX`, 140–390 тыс. знаков), одна средняя и 64 КРОШЕЧНЫЕ — страница «Contents», разрезанная конвертером на файлы по одной строке»; детерминированный заголовок непуст у **0 из 71**. Проекция цены всей книги $6.65, из них на 64 осколка **$0.38**. ⇒ ряд перестал быть теоретическим: не-CJK книга платит за оглавление как за главы. ⚠ Механизм группировки документов в коде ЕСТЬ (`backend/internal/chunk/epubtoc.go:293`=`func groupChapters`, привязывает неграничный документ к предыдущей главе) — значит вопрос не «построить», а «почему 64 осколка прошли как границы»; это и есть предмет замера перед стройкой. | бэкенд | скоро (ДО открытия беты не-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 приезжает в читалку с китайским названием — ломается первое, что видит человек. Владелец: «пусть едет как термины, причём отдельные, то есть как-то надо называть эту стадию». ⚠ Значит у стадии своё имя, свой бюджет и своя ПОДПИСЬ: название книги владелец утверждает так же, как утверждает термин. ✅ **ПОДПИСЬ РЕШЕНА ВЛАДЕЛЬЦЕМ 11.09, и она НЕ отдельный узел:** «это идет банком и делается автоподпись\подпись юзера просто, вот и все» ⇒ заголовки и название едут через БАНК ПАМЯТИ тем же механизмом подписи, каким подписывают термины; проектировать под них собственный узел подписи НЕ надо. ⚠ Родня — строка 274 (ручка переименования у пользователя) и открытый лист владельца «что печатать на титуле и в имени файла» (D25.1): механизм строится, СЛОВО остаётся за владельцем | бэкенд | скоро | стадия перевода заголовков, подпись — БАНКОВСКАЯ (авто либо пользовательская) | решение владельца 05.09, подпись решена 11.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, посадка вне списка автора | diff --git a/docs/NEAR_TERM_PLAN.md b/docs/NEAR_TERM_PLAN.md index 9e035e33..bbbe48a5 100644 --- a/docs/NEAR_TERM_PLAN.md +++ b/docs/NEAR_TERM_PLAN.md @@ -56,7 +56,7 @@ | 8 | **бэкенд/деньги** | ⛔ **«ПАДЕНИЕ, КОТОРОЕ ВИДНО»** — четверть COGS в одном механизме (**415**), слепые приборы отказа (**414**, **422**), молчащая подстановка цены. ⚠ Пин цены **413** из пака ВЫНУТ: это данные и отдельное решение | пак, $0 | ✅ **ЗАКРЫТ АКТОМ `D39.251`** (испр. 15.09; дальше — запись 11.09) · ✍️ **НАПИСАН 11.09** — `BACKEND_FAILURE_YOU_CAN_SEE_SESSION_PROMPT.md`; выдаётся СВЕЖЕЙ сессии сразу по закрытии 4 ⛔ **КРИТЕРИЙ ПРИЁМКИ ПАКА — МЕХАНИЗМ, А НЕ ПРОПОРЦИЯ** (поправка старшего коллеги 11.09): лекарство есть распространение ратифицированного образца `D2` п.3 на вторую причину, и оно верно при 25 % и при 5 % — пропорция задаёт очерёдность, не форму. ⇒ судить по строкам «ни одного удвоения без вердикта о вырождении; каждая выброшенная попытка — строкой леджера с причиной», а не по «с 25.4 % до X». Значит прогон B пак не гейтит и паком не гейтится.| | 9 | **платформа+бэкенд** | ⭐ **ХОЛОДНЫЙ ПРОГОН B — платформа → бэкенд → файл, ВТОРОЙ раз.** Уточнение владельца 11.09: спрашивая «перепрогоны нужны», он имел в виду именно сквозной прогон, а не пере-запуск тестов. Покупает ЧЕТЫРЕ вещи, которых нет ни у кого: **(1)** миграция **v17** (`wave_selection`) пака консистентности ни разу не шла на живом прогоне — только в тестах; **(2)** прибор консистентности впервые даст числа с ЖИВОГО прогона, а не с пере-скана сохранённой базы прогона A — сегодня все `I1`/`I2` получены повторным чтением одних и тех же данных; **(3)** платформенный пак (идемпотентный резюм, терминальное состояние) проверяется сквозь, а не юнитами; **(4)** ⛔ **вторая точка по денежной дыре, и она нужна по норме, а не для красоты** — весь довод «четверть денег купила пустоту» стоит на ЧЕТЫРЁХ одиночных розыгрышах, а квирки §3д прямо говорят: смета DeepSeek с одиночного вызова может ошибиться на порядок, сметы строятся на ПОВТОРАХ. ⇒ у числа 25.4 % есть знак и нет величины, пока прогон не повторён. **Цена ≈$0.42 по образцу прогона A, машинный кап ≈$2.5.** ⛔ **ПРЕ-РЕГИСТРАЦИЯ ЗНАМЕНАТЕЛЯ, иначе B ответит числом на другой вопрос** (поправка старшего коллеги 11.09): B — ЕЩЁ ОДИН одиночный прогон, и две точки распределением не станут. Настоящая ценность B не «вторая точка к 25.4 %», а `request_log` ВСЕХ единиц прогона ⇒ **доля выброшенных первых попыток ПО ЕДИНИЦАМ, а не по вызовам.** Это и пре-регистрируется. ⚠ И идёт B **ПАРАЛЛЕЛЬНО** паку о падениях, а не после: они в РАЗНЫХ слотах (бэкенд против платформы), и правило «один промт на зону» их не сталкивает | ≈$0.42 | ✅ **ЗАКРЫТ АКТОМ `D39.252`**, факт $0.396657 | | 10 | **бэкенд** | ✅ **ЗАКРЫТ АКТОМ `D39.266`** 17.09 (`d25e418`, 32 пути, $0): носитель — таблица `bank_basis`, миграция v19, аддитивная; ряд **490** закрыт по трём условиям, **130** получил ТРЕТИЙ исход (замысел достигнут другим механизмом, стоп-решение остаётся за владельцем), два отказа с замером, заведён **496**. Числа приёмки: кампания **315/315 поймано, выживших 0**; M1 — **67 из 69** и **64 из 66** обслужено из памяти. Прежняя формулировка предмета: ⛔ **БАНК: РЕШЁННОЕ ОСТАЁТСЯ РЕШЁННЫМ** — предмет пере-определён проверкой 15.09. Пак 12.09 «в банк по разнобою» (`archive/prompts/BACKEND_WHAT_THE_BANK_IS_MADE_OF_SESSION_PROMPT.md`) снят баннером: все термы со `spread ≥ 2` уже в банке (A 9 из 9, B 8 из 8). Настоящий дефект приоритета №1 — пере-решение банка терминологом: на подписи замерено (у неподписанных строк сменились передачи A 12 из 69, B 14 из 66), на каждой следующей покупке глав выведено из кода — отгруженные главы по порядку слотов остаются со старыми передачами (`backend/internal/pipeline/volume.go`, греп `DELIVERY BEFORE REWORK`). Ряды 130 · 330 · 438 · 440 | $0 + центы перекупки банк-ролей | ⛔ **ПРОЕКТ ОРКЕСТРАТОРА ОТОЗВАН 15.09.** «Банк — журнал решений с окнами» (две редакции Fable 5) расходился с 12 пунктами решённого, замеренного и этого же плана и опирался примерно на десятую часть относящегося; улики — `archive/reports/BANK_CONSILIUM_INPUTS_2026-09-15/`. ✅ **КОНСИЛИУМ ОТРАБОТАЛ, акт `D39.253` (16.09).** Итог — `research/35-bank-memory-consilium.md`: банк как решение по уликам с пятью событиями пересмотра, N-1 на построенном фильтре, N-3 на сборке вида, ряды бэклога 441–450. ✅ **СЛОВО ВЛАДЕЛЬЦА ПОЛУЧЕНО 16.09** (`D39.254`): держать решение между покупками — да · при невозможной безродовой форме — перестроить фразу, иначе «как лучше читается» · богаче контекст — да, меру решает замер M4 · голос и ты↔вы — строить. ⚠ **Вопрос об отказе терминолога ПЕРЕ-ОПРЕДЕЛЁН владельцем:** у банк-ролей нет ни ретрая, ни фоллбека (ряды 435, 438), и он считает это дырой ⇒ заведён ряд 451 «умный участок в точке банка», ряд 452 — голос. ✅ **ГРАНИЦЫ ДАНЫ ВЛАДЕЛЬЦЕМ 16.09** — «в границах ратифицированного», и слот бэкенда освобождён приёмкой `D39.255`. ✅ **ПАК 1 ПРИНЯТ 16.09 актом `D39.257`** (29 путей, $0; посылка В1 закрыта замером — 25 из 26 при идентичном входе). Промт написан был 16.09 — `BACKEND_BANK_ZERO_LAYER_SESSION_PROMPT.md`, пак $0 (громкий отказ при цели без инъекционных текстов до первой траты · отказ роли перестаёт ехать законом · предикат «спорный» как ДВА предиката с заданными знаменателями · носитель посылки «новой улики не было»); круг опровергателя пройден. ✅ **ВЫДАН и ПРИНЯТ 16.09** — акт `D39.257`. Вопросы владельцу, в том числе ряд 130 (`research/34` §4 п.4), ставит его итог; он же решает порядок относительно 5(в). Довод «перекрой глав без якоря пере-решил бы банк платной книги» остаётся входом ✅ **ПЕРЕНОС БАНКА РЕШЁН ВЛАДЕЛЬЦЕМ 16.09 — акт `D39.256`:** в КНИГУ-ПРОДОЛЖЕНИЕ едут ПОДПИСАННЫЕ строки ПЛЮС строки, РЕШЁННЫЕ ДВИЖКОМ; стройка ДВУХЗОННАЯ и ещё не начата — ряд **461**. ⚠ **Эррата 16.09-б:** формулировка «причина смен передачи — якорь» в `D39.256` и `D39.257` СИЛЬНЕЕ замера — измерено лишь отсутствие новой улики во ВХОДЕ, причина остаётся гипотезой, гейт — ряд **466**. Прочее живое банка: ряды **462** · **465**. ⭐ **ЗАКАЗАН 17.09: промт «РЕШЁННОЕ НЕ ПЕРЕ-СПРАШИВАЕТСЯ» ВЫДАН** сессии `textmachine-main-57` (выдача №14, `docs/BACKEND_SETTLED_STAYS_SETTLED_SESSION_PROMPT.md`, $0). Строит базис решённого как ИСТОЧНИК ОТВЕТОВ (ряд 130) и стража разрыва окон (ряд 490); замер M1 идёт ПЕРВЫМ блоком, и носитель не пишется, пока оркестратор не принял форму предиката по числам. ⚠ **Состав сузился против проекта консилиума, и это измерено, а не решено вкусом:** N-4 и Б-5 ПОСТРОЕНЫ паком `D39.257`; N-6 гейчен разморозкой фронта (ряды **214** · **221**); Б-2 протух — токен «stops loudly» живёт только в тесте; N-3 и стратифицированный отбор вынесены НАРУЖУ, каждый со своим замером. Промт прошёл два рубежа (механическая сверка 13 блоков и субагент-опровергатель: 12 находок, 9 денежных, все внесены) и всё равно был исправлен релеем после выдачи — материал замера указывал на другую книгу. | -| 11 | **бэкенд** | ⭐ **ОКНО ПЕРЕ-КРОЯ — ВСЁ, ЧТО ДВИГАЕТ НАРЕЗКУ И ДАННЫЕ ПАРЫ, ЕДЕТ ДО СТАРТА ХОЛОДНОГО ПРОГОНА.** Открыто 18.09 покупкой прогона B, закроется стартом прогона — см. 5(в). Состав: **283** + **303** (родственные: грамматика не участвует там, где решают границу; пак 2 по 303 снимает запрет `D39.224` п.7) · **201** (движковое «Глава N» внутри текста) · **410** (голос построен сквозь и выключен двумя тумблерами, конфиг-ключа нет) · вынос свёрток нормализации источника из ядра в данные пары. ⛔ **Порядок задан владельцем 18.09, дословно: «цель: не бежать поскорее приступить к холодному прогону а подготовить бэкенд так что б этот холодный прогон исполнить максимально правильно. Сколько паков и бэклога нам для этого нужно закрыть не очень важно. Халтурить не надо, подгонять тоже ничего не надо, спиливаем долг из бэкенда, реализуем актульный, нужный чистый архитектурно код».** ⇒ число паков перестало быть ограничением, и «успеть к прогону» перестало быть доводом за срез | паки, $0 | ✍️ **ПАК 1 НАПИСАН 18.09** — `BACKEND_CHAPTER_STRUCTURE_SESSION_PROMPT.md` (границы глав; корень найден подсказкой владельца — см. «СОСТОЯНИЕ НА 18.09»). Не выдан: идёт второй рубеж | +| 11 | **бэкенд** | ⭐ **ОКНО ПЕРЕ-КРОЯ — ВСЁ, ЧТО ДВИГАЕТ НАРЕЗКУ И ДАННЫЕ ПАРЫ, ЕДЕТ ДО СТАРТА ХОЛОДНОГО ПРОГОНА.** Открыто 18.09 покупкой прогона B, закроется стартом прогона — см. 5(в). Состав: **283** + **303** (родственные: грамматика не участвует там, где решают границу; пак 2 по 303 исполняет запрет `D39.224` п.7) · **201** (движковое «Глава N» внутри текста) · **410** (голос построен сквозь и выключен двумя тумблерами, конфиг-ключа нет) · вынос свёрток нормализации источника из ядра в данные пары. ⛔ **Порядок задан владельцем 18.09, дословно: «цель: не бежать поскорее приступить к холодному прогону а подготовить бэкенд так что б этот холодный прогон исполнить максимально правильно. Сколько паков и бэклога нам для этого нужно закрыть не очень важно. Халтурить не надо, подгонять тоже ничего не надо, спиливаем долг из бэкенда, реализуем актульный, нужный чистый архитектурно код».** ⇒ число паков перестало быть ограничением, и «успеть к прогону» перестало быть доводом за срез | паки, $0 | ✍️ **ПАК «ГРАНИЦА ГЛАВЫ» НАПИСАН 18.09** — `BACKEND_CHAPTER_STRUCTURE_SESSION_PROMPT.md`; по ряду 303 он и есть «пак 2» (`D39.270` п.1: запрет `D39.224` п.7 им ИСПОЛНЯЕТСЯ, а не снимается), и 346(б) едет в нём же (`D39.270` п.7). Корень найден подсказкой владельца — см. «СОСТОЯНИЕ НА 18.09». Три круга проверки, третий изменил ПРЕДМЕТ: резка внутри документа необходима, граница — объединение двух наборов | ⛔ **ПОЧЕМУ 4 ВСТАЛ ПЕРЕД 5 (решение 11.09 по мерилу владельца).** Мерило — «качественный КОНСИСТЕНТНЫЙ перевод длинных книг». Аудит банка 11.09 показал, что **книжного вопроса о консистентности не задаёт ни один diff --git a/docs/README.md b/docs/README.md index 5e1a6d2a..c062098f 100644 --- a/docs/README.md +++ b/docs/README.md @@ -24,7 +24,7 @@ - **Активные хендофф-промты — какой файл ТВОЙ** (состав обновляется при каждом лендинге, D39.80; хроника, причины и статусы РАБОТ — CURRENT-STATE и D-лог): | Роль | Активный промт | Статус | |---|---|---| -| **Бэкенд · ГРАНИЦА ГЛАВЫ** | [BACKEND_CHAPTER_STRUCTURE_SESSION_PROMPT.md](BACKEND_CHAPTER_STRUCTURE_SESSION_PROMPT.md) | ⭐ **ВЫДАН 18.09, акт `D39.270`** — этот промт ЕСТЬ «пак 2» по ряду **303**, и запрет `D39.224` п.7 им ИСПОЛНЯЕТСЯ, а не снимается (промт заказ, не ратификация ⇒ именование живёт нотой). Предмет нашёл владелец: грамматику источника получает только текстовый путь ингеста, `ingestEPUB` не получает её вовсе ⇒ на EPUB границу назначает навигация издателя единолично. Фактура: целей навигации 71 (6 частей + 65 глав) · тождеств 60 · документов spine БЕЗ цели **55 из 126, и это вся проза** · настоящих глав **81 плюс пролог** · ярлык есть склейка двух абзацев прозы, но **0/81 побайтно и 65/81 при нормализации** ⇒ 16 глав навигация не называет. ⛔ Пак СДВИНЕТ ключ манифеста и КИТАЙСКОЙ книги (эррата 18.09-б к `D39.269` B1) и протушит пре-регистрированные числа пака прогона ⇒ лендится ДО фриза. Два круга опровержения: 14 находок (9 мажоров) и ещё 10 — все обязательные внесены; шесть моих утверждений, звучавших замером, оказались выводами. Живое сверх пака: ряды **283** · **284** · **201** · **302** | +| **Бэкенд · ГРАНИЦА ГЛАВЫ** | [BACKEND_CHAPTER_STRUCTURE_SESSION_PROMPT.md](BACKEND_CHAPTER_STRUCTURE_SESSION_PROMPT.md) | 🔴 **ВЫДАН 19.09 → `textmachine-main-7b`** (свежая: паков не брала, по репо ни одного вызова — проверено опросом). ⛔ СЛОТ БЭКЕНДА ЗАНЯТ. Именование и границы — акт `D39.270`: этот промт ЕСТЬ «пак 2» по ряду 303, запрет `D39.224` п.7 им ИСПОЛНЯЕТСЯ; 346(б) едет в нём же (п.7). Предмет нашёл владелец: грамматику получает только текстовый путь ингеста. Три круга проверки, третий изменил ПРЕДМЕТ: граница — объединение двух наборов (12 глав в документах с целью), резка внутри документа необходима (28 документов по 2–7 глав), единица правила — абзац (построчно 20 ложных «I»). Решение не вправе зависеть от книжных данных (п.8). ОК советчика на финальный текст получен. ⛔ Пак СДВИНЕТ ключ манифеста китайской книги (эррата 18.09-б к `D39.269`) ⇒ лендится ДО фриза прогона. $0 | | Бэкенд · ДОСТИЖИМОСТЬ ПАР-ДАННЫХ | активного НЕТ | пак ОТРАБОТАН и **ПРИНЯТ 18.09** — акт **`D39.268`**, лендинг `9defda4` (38 файлов, 1855/66, $0) + `e6f9a3b`; промт в `archive/prompts/` с баннером. Кампания **336/336 поймано, 0 выживших, 0 НЕ ИЗМЕРЕНО**. ⭐ Предмет пере-определён замером ДО выдачи: языковых ветвлений в Go шесть при контроле 154 файла, живых два и оба законны ⇒ остаточная зависимость есть НЕДОСТИЖИМОСТЬ ДАННЫХ. **Английская книга доезжает на боевом конфиге** и встаёт на потолке до первого вызова. Ряды 347 и 500 закрыты, 272 и 502 половинами | | Бэкенд · АНГЛИЙСКАЯ ПАРА en→ru | активного НЕТ | пак ОТРАБОТАН и **ПРИНЯТ 18.09** — акт **`D39.267`**, лендинг `ddadb3e` (32 файла, 1356/127, $0) + `63e3a0d`; промт в `archive/prompts/` с баннером-исходом. Кампания **327/327 поймано, 0 выживших, 0 НЕ ИЗМЕРЕНО**, сумма исходов = составу гейта. ⭐ Пак заменил защиту, державшуюся ОТСУТСТВИЕМ второго промт-пакета, на механизм, и нашёл это у себя сам. Живое продолжение предмета — пак достижимости пар-данных | | Платформа · ПРОГОН НЕ ВРЁТ О СЕБЕ | активного НЕТ | пак ОТРАБОТАН и **ПРИНЯТ 17.09** — акт **D39.265** (32 пути, $0, контрактный минор **0.17.0**); промт в [archive/prompts/](archive/prompts/PLATFORM_RUN_TELLS_THE_TRUTH_SESSION_PROMPT.md) с баннером-исходом. Ряды **398** · **399** · **400** · **486** закрыты работой, **394** и **396** — ПЕРЕ-РЕШЕНИЕМ (четвёртое значение в клиентский словарь не идёт: «мы сами перестали перезапускать» — другая ось, чем «стоит ли повторять», и границу между осями стережёт новый гейт на три носителя), **416** — платформенной половиной. Кампания пере-снята приёмкой: 26 записей · поймано 25 · выжила 1, объявленная ДО прогона · неизмеренных 0. ⛔ Гейт зоны красен на экземпляре ряда **484** (фикстурный бюджет записи под нагрузкой; оба упавших теста живут в чистом `HEAD`) — названо границей, а не зеленью. ⚠ Две ошибки приёмки названы в акте: оркестратор взял себе правку канона (откачена) и неточно сформулировал §4.1 промта. Живое — ряды **416** (движковая половина) · **484** · **493** · **494** | diff --git a/docs/architecture/05-decisions-log.md b/docs/architecture/05-decisions-log.md index 93e0f1b1..4bae65a9 100644 --- a/docs/architecture/05-decisions-log.md +++ b/docs/architecture/05-decisions-log.md @@ -5084,7 +5084,59 @@ $0.38 из $6.65) измерен, не починен · **303** не трону одном приборе. Первый мой счётчик дал 3 главы вместо 84, потому что регексп требовал `class` первым атрибутом, а первым стоит `id`; поймано печатью контрольной величины рядом с числом, и только ею. -**6. ГРАНИЦА АКТА.** Акт утверждает ИМЕНОВАНИЕ пака 2 и выдачу промта. Он НЕ утверждает: судьбу пролога (её +**6. ГРАНИЦА АКТА.** Акт утверждает ИМЕНОВАНИЕ пака 2. ⚠ **Выдачу он НЕ утверждает** (испр. той же сменой: первая редакция писала «и выдачу промта», тогда как адресата на момент записи не было — дефект, который оркестраторская нота называет в «Кому выдавать?»); адресат фиксируется строкой ниже при передаче. Акт НЕ утверждает также: судьбу пролога (её объявляет сессия числом в §4.4) · форму лечения ряда 303 (дизайн §8.2 не ратифицирован) · что имя главы доедет до книги читателя — замерено, что НЕ доедет (`TitleRaw` в билдере выдачи 0 вхождений, заголовок берётся из `backend/internal/pipeline/bookbuild.go:554`=`t := ce.Heading`), и это остаётся долгом рядов 284 и 201. + +⚠ **ИСПРАВЛЕНИЯ ТОЙ ЖЕ СМЕНЫ ПОСЛЕ ТРЕТЬЕГО КРУГА (аудит-воркфлоу по оркестраторской ноте: сверка 13 блоков, +актуальность против бэкенда, листы владельца, критик полноты; 25 мажоров, 22 подтверждены критиком по дереву, +два опровергнуты в деталях). Пункты 1–6 выше остаются как написаны; вот что в них неверно:** +- п.1, «единственные вхождения имени — сам п.7 и ряды 302/303» — ложно: имя встречается ещё в дизайне, его + отчёте, `research/33` и `NEAR_TERM_PLAN.md`. Верная форма: **в РАТИФИЦИРОВАННОМ тексте «пак 2» не определён.** +- п.3, «55 документов без цели — это вся проза книги» — сильнее замера: 55 = 35 прозаических + 20 прочих, и + среди прочих `index_split_058` и `_124` — текст оглавления вне навигации. «Настоящих глав 81 плюс пролог» — + неполно: разделов без номера ДВА (`SUNSET` и `DAWN`), и печатное оглавление книги даёт Dramatis Personae · + Sunset · 81 «Chapter» · Dawn. «5 осколков» — это 4 с именем следующей части и 1 с хвостом оглавления. +- п.4, свидетель «`-none`» — английский; ключ китайской книги двигает версия нарезки + (`backend/internal/pipeline/manifest.go:383`=`Chunker: chunkerVersion` и + `backend/internal/pipeline/snapshot.go:463`=`ChunkerVersion: chunkerVersion`), а не отпечаток. Протухают не + только пре-регистрированные числа, но и ТЕКСТ промта прогона (блок про «шесть глав»); переписывает его + оркестратор, а не пак прогона. + +**7. РЯД 346 (б) ЕДЕТ В ЭТОМ ПАКЕ — ОТСТУПЛЕНИЕ ОТ `D39.224` п.4(а) РАТИФИЦИРУЕТСЯ ЗДЕСЬ.** Тот пункт держит +«шаги 2+3 — ОДНА перенарезка», и ряд 346 ставил свою половину (б) в шаг 3. Этот пак — сам перенарезка (он двигает +версию нарезки), и сведение двух предикатов заголовка к ингестовским стражам — тот же предмет «что есть +заголовок». Оставить его на потом значит ВТОРАЯ перенарезка; её цена $0 при условии `D39.224` п.5 (никто не +продолжает книгу), и это условие сегодня исполнено. ⇒ 346(б) внутри пака; паритет-пин, краснеющий при фиксе, +переворачивается как заказанная смена поведения. + +**8. ЗНАНИЕ О ЗАГОЛОВКАХ КНИГИ ПРОГОНА НЕ ВПРАВЕ ЗАВИСЕТЬ ОТ КНИЖНЫХ ДАННЫХ — решено оркестратором, не вопрос +владельцу.** Книга через API платформы получает `book.yaml` из одного шаблона оператора +(`platform/internal/config/config.go:259`=`BookTemplate is the operator's starting`), крой снимается на интейке, +и книжной ступени грамматики нет. ⚠ **Испр. тем же днём (третий круг советчика):** первая редакция опиралась на «ручная правка `book.yaml` после интейка была бы девиацией» — и противоречила моему же паку прогона, который такую правку РАЗРЕШАЕТ с объявлением девиации (`docs/COLDRUN_TWO_BOOKS_SESSION_PROMPT.md`, развилка шаблона перед интейком). Опора верная — не процедура, а предмет: грамматика, вписанная руками в `book.yaml` одной книги, есть механизм под книгу, и довод владельца против неё прямой. Решение следует из его слов, поэтому вопросом не ставится: «Бэкенд не +должен иметь конкретных механизмов под язык\книгу, максимум в данных и то они так же должны хорошо отрабатывать +где этих французских слов нет». ⇒ источники: то, что несёт сама книга (тождество, имена навигации, печатное +оглавление) и языковые данные источника с доказанной инертностью на корпусе. Книжная ступень не запрещена, но +пак от неё не зависит. + +**9. ГЕЙТ `D39.136` п.3 («стройка после ратификации дизайна») К ЭТОМУ ПАКУ НЕ ОТНОСИТСЯ, и сказано почему.** Он +стоит на Этапе 1 — ряде 161, «большом перекрое» (идентичность главы, миграции, судьба переведённых книг). +Этот пак — ряд 303 и источники границ; большой перекрой он не строит. Дизайн +`backend/docs/CHAPTER_STRUCTURE_DESIGN.md` служит ему источником ФОРМЫ, а не санкцией. + +**10. ТРЕТИЙ КРУГ ИЗМЕНИЛ ПРЕДМЕТ, А НЕ ФОРМУЛИРОВКИ — три находки, все пере-сняты мною.** (а) **12 номеров глав +лежат в документах, у которых ЕСТЬ навигационная цель** ⇒ граница есть объединение двух наборов, а не +«грамматика там, где навигация молчит». (б) **28 документов несут по 2–7 глав** ⇒ резать внутри документа эту +книгу НЕОБХОДИМО; форма ряда 302 входит в пак грамматическим свидетелем (якорная форма — нет). (в) **Построчная +машина заголовков даёт 104 вместо 84, из них 20 ложных «I» в стихах**; 84 по строкам выходит на английской паре +лишь через глиф курсива пары — верный ответ неверным методом. ⭐ Класс, ради которого записано: **трижды подряд +промт был верен в ЧИСЛЕ и неверен в ПРЕДМЕТЕ** — и ни одно из трёх не видно, пока спрашиваешь «сколько глав», +а не «через какую единицу и в каком документе». + +**11. ПОТОЛОК СОВЕТЧИКОВ ДЛЯ ЗОННОЙ СЕССИИ — ДО ДВУХ (`D39.258` п.9), и я назвал его неверно.** Первая редакция +промта и моё сообщение кандидату говорили «один» — по `CLAUDE.md`, который отстаёт от ноты 17.09. Кандидату +отправлена поправка; строка `CLAUDE.md` приведена к ноте. ⚠ Дрейф повторялся и раньше +(`BACKEND_RUN_READINESS`, 18.09) — источник у него один. + +**12. ВЫДАЧА (19.09).** Адресат — `textmachine-main-7b`, свежая: на опрос ответила, что паков не брала и по репозиторию не сделала ни одного вызова; кроме неё живых сессий после рестарта среды нет. Три круга проверки пройдены: механическая сверка по оркестраторской ноте (29 пунктов канона, 0 битых якорей, контроль 31 из 31 красных) · опровергатель по листам владельца (аудит-воркфлоу: 25 мажоров, 22 подтверждены) · советчик — три круга, последний «ОК после пяти правок», правки подтверждены им же. ⛔ СЛОТ БЭКЕНДА ЗАНЯТ до акта закрытия этого пака. diff --git a/docs/orchestrator-norms-scratchpad.md b/docs/orchestrator-norms-scratchpad.md index 6f04d5de..1dbbc99e 100644 --- a/docs/orchestrator-norms-scratchpad.md +++ b/docs/orchestrator-norms-scratchpad.md @@ -58,8 +58,7 @@ | Зона | Промт | Сессия | Состояние | |---|---|---|---| -| бэкенд | `BACKEND_BOUGHT_MEANS_DELIVERED_SESSION_PROMPT.md` | ~~textmachine-b1~~ → свежая | ⛔ **СЕССИЯ b1 ПОТЕРЯНА 15.09** при переезде окружения (`textmachine-main-b1` — пустая сессия владельца, НЕ b1). Пак не завершён: круги не сошлись, нет «Чисел», таблицы мутаций, строки завершения. Сдача — в индексе main (sha `git diff --cached --binary` = `166997963c95…`), бэкап `~/tm-b1-orphan-index.patch`, копия только для чтения `~/tm-b1-orphan`; гейт на копии зелёный (19 ok · 0 FAIL · lint 0 · 9 скипов · 23/23). Передача — разделом ред. 5 того же промта; опровергатель к нему сошёлся за три круга (21 → 3 мажора → 0 мажоров, шесть миноров последнего внесены); выдан 15.09 сессии `textmachine-main-b1` словом владельца «выдай ему», confirm по слову 11.09 получен (эррата 15.09-а); эхо ✅. ⏸ **СДАН 15.09 ПО ПРАВИЛУ ОСТАНОВКИ П4** — круги не сошлись, остаток в таблице; со слов сессии: 29 путей, сырьё каталога вне репо в `/home/ubuntu/tm-mut-logs-final-1509`, числа мною не пере-сняты. **Приёмка отложена словом владельца** «Не отвлекайся пока от банка памяти, работай по нему» | -| бэкенд | `BACKEND_ENGLISH_PAIR_SESSION_PROMPT.md` | `textmachine-main-c5` | 🔴 **ЗАНЯТ 17.09** — пак АНГЛИЙСКОЙ ПАРЫ en→ru выдан; слот освободил акт `D39.266`, а не сдача работы. Центр пака — **СЛОЙ ДАННЫХ английского языка** (слово владельца 17.09: «данные надо написать… уникально описать английский язык… от этого качество перевода зависит»); Fable 5 разрешён исполнителю ОДИН, под верификацию ДАННЫХ. Два рубежа пройдены: механическая сверка 13 блоков (29 адресов, битых 0) и опровергатель — 15 находок, из них **ЧЕТЫРЕ мои ошибки ПОПУЛЯЦИИ** (мерил документ там, где движок читает группу). $0 по умолчанию, единственная платная проба — через моё слово. ⚠ **Противоречие с рядом выше не снимаю молча:** строка про `b1`/`BOUGHT_MEANS_DELIVERED` описывает незавершённый пак потерянной сессии от 15.09; две бэкендные строки в одной таблице спорят с правилом «один промт на зону», и диспозиция этого ряда — отдельный вопрос владельцу, а не моя тихая правка | +| бэкенд | `BACKEND_CHAPTER_STRUCTURE_SESSION_PROMPT.md` | `textmachine-main-7b` | 🔴 **ЗАНЯТ 19.09** — пак «ГРАНИЦА ГЛАВЫ» («пак 2» по ряду 303, акт `D39.270`); слот освобождает акт закрытия. ⚠ Прежние строки этой зоны протухли: пак BOUGHT_MEANS_DELIVERED закрыт `D39.255` 16.09, пак английской пары — `D39.267` 18.09, пак достижимости — `D39.268` 18.09 | | платформа | — | — | 🟢 **СЛОТ СВОБОДЕН** — пак «прогон не врёт о себе» принят актом `D39.265` 17.09, минор **0.17.0**, лендинг `bde8f5f`. ⚠ Свежей сессии в резерве НЕТ; приоритет следующего платформенного заказа у владельца не подтверждён — «слот свободен» ≠ «работу зоны надо заказывать». Кандидаты, если спросит: операционная гигиена входа (ряды регистра `PD-443` · `PD-433` · `PD-102` · `PD-162` · `PD-175`) и свежие 493 · 494 | | полигон | — | — | ⛔ **ЗАКАЗ СНЯТ ВЛАДЕЛЬЦЕМ 11.09** («полигон не надо выдавать»); промт готов и лежит, пере-выдача — только его словом | | сквозной (вне кодовых зон) | — | — | ✅ **ЗАКРЫТ актом `D39.252`** 11.09; промт в архиве с баннером. Стенд поднят до конца приёмки, гасить по pid | @@ -123,6 +122,7 @@ UNKNOWN 1 — её, дошёл один раз до правок; десять | 15 | платформа | ПРОГОН НЕ ВРЁТ О СЕБЕ — ни оператору, ни покупателю, ни счёту: ряды 398 · 394 · 396 · 399 · 400 · 416 · 486 | textmachine-main-78 | ✅ эхо блока 9 отослано | ✅ **ЗАКРЫТ АКТОМ `D39.265` 17.09**, лендинг `bde8f5f` (41 файл, $0, контрактный минор **0.17.0**). Ряды 398·399·400·486 закрыты работой, 394 и 396 ПЕРЕ-РЕШЕНИЕМ, 416 половиной; заведены 493 и 494, дополнен 484. ⛔ **Гейт зоны на финальном дереве КРАСЕН и назван ГРАНИЦЕЙ, а не зеленью** — экземпляр ряда 484, оба упавших теста живут в чистом `HEAD`. Приёмка: кампания пере-снята мной 26/25/1/0 на отдельном корне её же харнессом, копия вернулась байт-идентичной, все 26 целей на месте; деньги $0 двумя путями; две линзы (слепая по заказу и диффу, вторая вне карты отчёта) дали три настоящих находки, две из них в каноне. ⚠ **МОИ ошибки, обе в акте:** взял себе правку канона, принадлежащую ЗОНЕ (откатил, дифф 0 строк, поймал ВЛАДЕЛЕЦ) и неточная посылка §4.1 промта. ⚠ Плюс три дефекта собственных приборов, каждый пойман печатью контроля рядом с числом: шапка манифеста прочитана как пары «хеш—имя» (23 ложных расхождения при 37/37 сошедшихся), греп маркера у пойманных мутаций (маркеры стоят только у выживших, намеренно), «0 скипов» из сводки, оборванной падением (в полном логе 10). ⏳ **ВЫДАН 17.09.** Собран ВЕЕРОМ из четырёх срезов за один заход — против девяти последовательных кругов, которыми я собирал предыдущий пак; это и есть разница в способе работы, а не во времени. Оба рубежа пройдены: механическая сверка 13 блоков (18 якорей с токеном, промахов 0, голых адресов 0) и опровергатель — **10 находок, 4 денежные, все внесены**. ⛔ **Самая дорогая — против меня: §4.2 заказывал ПОСТРОЕННОЕ.** Я написал, что наш собственный грейс читается как авария; вылечено 11.09 (`platform/internal/runs/reconcile.go:1226`=`return "interrupted"`, два пина в `gracekill_test.go`, коммит `00d590e`, принято `D39.242`), а ряд 394 протух и я поверил ряду вместо дерева. ⚠ Ещё три денежные: предмет капа уже стоит в регистре зоны весом `info` с прописанным лечением, а я назвал его «самым денежным» · механизм счётчика описал неверно (он живёт на ПОПЫТКЕ, а рестарт открывает новую строку, поэтому кап на попытку повторил бы дефект) · согласие нельзя сделать соразмерным силами платформы: проекции в точке решения нет по построению, и код это записал со ссылкой на эрратy, а ряд размечен двухзонным. ⚠ И ловушка, которой не было в первой редакции: словарь причин отказа закрыт в ТРЁХ носителях, включая констрейнт базы, и не стережётся НИ ОДНИМ гейтом (0 хитов при контроле 12 у соседа) — четвёртое значение прошло бы `make check` зелёным и упало в проде | | 16 | бэкенд | АНГЛИЙСКАЯ ПАРА en→ru: слой ДАННЫХ английского языка как ПРОДУКТ (слово владельца 17.09 — «данные надо написать… уникально описать английский язык… от этого качество перевода зависит»), две стены `EXIT 10` (нет промт-пакета пары · гейт терминолога при пустом паке), порог эха `0.15` унаследован от китайского бенчмарка, второй детектор латиницы без гейта, нарезка книги Кристоффа | `textmachine-main-c5` | ✅ **эхо принято 17.09** — своими словами, семь пунктов, механика а не текст; ⭐ в нём взята ПОПУЛЯЦИЯ ГРУППЫ, а не документа, то есть моя собственная ошибка первой редакции НЕ унаследована, и сквозная проверка манифеста поставлена ПЕРЕД письмом данных | 🔴 **ИДЁТ** — выдан после акта `D39.266`, слот освободил акт, а не сдача работы. Два рубежа промта пройдены: механическая сверка 13 блоков (29 адресов, битых 0) и субагент-опровергатель — **15 находок, 9 приняты, 6 уточнены моими числами**, из них ЧЕТЫРЕ мои ошибки ПОПУЛЯЦИИ (документ вместо группы · отозванная формулировка ряда 315 прочитана как живая · строка ноты обрезана на 200 знаках и объявлена «телом без содержимого» · сравнение лучшего префикса с перелётом). ⚠ Fable 5 разрешён исполнителю ОДИН — владельцем и именно под верификацию ДАННЫХ. $0 по умолчанию; единственная платная проба — через моё слово. ⛔ Открытый вопрос владельцу, сессии сообщён: размеченного корпуса для en→ru нет вовсе, человеческий эталон вне репозитория ⇒ качество данных числом не предъявимо, и самодельную метрику заводить запрещено | | 17 | бэкенд | ДОСТИЖИМОСТЬ ПАР-ДАННЫХ перед прогоном: манифест нулевых каналов (347) · сайзинг терминолога · курсив на провод (500) · пар-связанные ключи брифа (272) · исход при упоре в баланс провайдера (502) · омографы латинских ключей банка | `textmachine-main-c8` | ✅ **эхо принято 18.09** — своими словами, механикой; ⭐ её формулировка сильнее моей: «§4.1 первым, потому что он **не пункт, а условие измеримости**». Названо и то, чего НЕ делает: диакритику не возвращает, инлайн-теги в блочный набор не кладёт, версию промта не бампает, файл структуры не заводит | 🔴 **ВЫДАН 18.09**, лендинг `dbbfd52`. ⛔ **ПРЕДМЕТ ПЕРЕ-ОПРЕДЕЛЁН ЗАМЕРОМ ПО ДОРОГЕ, и это главное открытие дня:** я заказывал «убрать китайское из Go», а перепись дала **шесть упоминаний кодов языка при контроле 154 файла, живых ветвлений два, оба законны**. ⇒ остаточная зависимость движка от одной пары есть **НЕДОСТИЖИМОСТЬ ДАННЫХ**, а не грязь в коде. Три рубежа, каждый сломал своё: **опровергатель** — 8 мажоров, из них ТРИ моих якоря целили не туда (включая файл, которого в дереве нет), и один пункт вынут замером (гейт латиницы: на прогоне не меняет ничего, что видит модель, а бамп версии двигает снапшот ОБЕИХ книг); **пять верификаторов** — пере-сняли исполнением, что английская книга ГРОМКО отказывает до первого цента, корень один, снимается тремя строками, китайский пакет байт-идентичен; **ревью сдавшей сессии** — нашло то, чего не увидели первые два: §4.2 был ВЕРЕН построчно и позволял **закрыть пункт, не сделав работу** — исполнитель прошёл бы все проверки, написал честный отчёт, и в платный прогон уехал бы китайский по форме размер батча. ⭐ Класс находки: **линза «где формулировка заказа позволит отчитаться, не сделав» ловит то, что не ловит линза «найди неверное»** | +| 18 | бэкенд | ГРАНИЦА ГЛАВЫ: грамматика на обоих путях ингеста (ряд 303 — «пак 2», `D39.270`) · тождество ярлыка и тела · граница как объединение навигации и грамматики · резка внутри документа · провенанс смешанной нарезки · 346(б) · система счисления данными | `textmachine-main-7b` | ждёт эха | 🔴 **ВЫДАН 19.09.** ⭐ Предмет нашёл владелец одной фразой — «статический код … должно склеиваться»: `ingestEPUB` грамматики не получает. ⛔ Три круга проверки, и ТРЕТИЙ изменил предмет, а не формулировки; в первых двух я шесть раз подал вывод как замер. Второй рубеж сперва был проведён не в форме ноты (опровергатель мерил факты, а не соответствие 13 блокам и листам владельца) — пере-проведён воркфлоу. «ВЫДАН» было записано в README до того, как нашёлся адресат, — снято и возвращено только сейчас | ⛔ **ПОЛИГОН СНЯТ ВЛАДЕЛЬЦЕМ 11.09.** Я предлагал пак трижды — `ed`, `5c` (обе отработавшие, отказались ПО НОРМЕ и были правы) и свежей `37`, — после чего владелец сказал «полигон не надо выдавать». Выдача `37` ОТОЗВАНА тем же часом. ⚠ Урок не про полигон: **я трижды искал адресата для заказа, приоритет которого не подтверждал у владельца.** Слот зоны свободен ≠ работу зоны надо заказывать.