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

This commit is contained in:
heaven 2026-09-19 00:12:58 +03:00
parent 7f8f08c2b1
commit d7fb918a1c
7 changed files with 338 additions and 355 deletions

View file

@ -350,7 +350,7 @@ Go-бэкенд издательского художественного пер
ровно там, где предмет. Вопрос себе: «сколько раз этот файл переписывается за прогон и какой из разов
я сейчас читаю?»
⭐ **Пришло письмо «всё закрыто» — иди перечитывать СВОИ утверждения о закрытом, а не чужие правки.**
**Fable 5 — ПОТОЛОК 12 АГЕНТА НА СЕССИЮ, слово владельца 11.09: «я не разрешаю больше 1-2 на сессию».** Прежняя редакция называла это рекомендацией — она отозвана. Модель задавай агенту ЯВНО и знай, сколько их у тебя работает. ⚠ И форма важнее числа: **одному агенту с ПОСТОЯННЫМ контекстом дослылают вопросы, а не поднимают второго** — контекст и есть ценность. Опус-субагенты потолком не ограничены, но тратятся так же. ⭐ **Дополнение владельца 11.09: потолок относится к КАЖДОЙ сессии, и зонная сессия тоже вправе держать СВОЕГО фабла-советчика — ОДНОГО.** Слово дословно: «разрешаю 1 фабла на 1 сессию, ну как у тебя». ⇒ промт зоны это НАЗЫВАЕТ: как поднять (`model: "fable"` явно), о чём спрашивать (сомнение · развилка · «не построено ли уже» · «не противоречит ли ратифицированному»), и что он СОВЕТЧИК, а не источник истины — его посылки проверяются деревом.
**Fable 5 — ПОТОЛОК 12 АГЕНТА НА СЕССИЮ, слово владельца 11.09: «я не разрешаю больше 1-2 на сессию».** Прежняя редакция называла это рекомендацией — она отозвана. Модель задавай агенту ЯВНО и знай, сколько их у тебя работает. ⚠ И форма важнее числа: **одному агенту с ПОСТОЯННЫМ контекстом дослылают вопросы, а не поднимают второго** — контекст и есть ценность. Опус-субагенты потолком не ограничены, но тратятся так же. ⭐ **Дополнение владельца 11.09: потолок относится к КАЖДОЙ сессии, и зонная сессия тоже вправе держать СВОЕГО фабла-советчика — ОДНОГО.** Слово дословно: «разрешаю 1 фабла на 1 сессию, ну как у тебя».**СМЯГЧЕНО 17.09 нотой `D39.258` п.9 (журнал бьёт этот файл):** зонной сессии — ДО ДВУХ советчиков с постоянным контекстом, и советоваться предписано на ПРОЕКТИРОВАНИИ и на ПРИЁМКЕ, а не только при затруднении; карта чтения промта — минимум, `docs/` грепается в любое время. Отставание этой строки дважды дало неверный промт (18.09). ⇒ промт зоны это НАЗЫВАЕТ: как поднять (`model: "fable"` явно), о чём спрашивать (сомнение · развилка · «не построено ли уже» · «не противоречит ли ратифицированному»), и что он СОВЕТЧИК, а не источник истины — его посылки проверяются деревом.
- **Git-координация мультисессий:**
- **Коммитит только оркестратор.** Сессии зон — бэкенд, полигон, фронт, платформа — не коммитят: своё дерево готовят и передают на лендинг (исключение: пре-рег фризы полигона). Чужую зону не трогает НИКТО.
- **Форма коммита — ТОЛЬКО с явным списком путей: `git commit -- <путь> <путь>`.** Причина механическая: голый `git commit` уносит **ВЕСЬ индекс**, включая чужие застейдженные файлы, и чужая работа уезжает под твоим сообщением. Pathspec-форма индекс не трогает.

View file

@ -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`, 1482 тыс. знаков).
| что | число |
|---|---|
| целей навигации | **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** (по 27) |
| ярлык навигации против «номер + имя» из прозы | побайтно **0 из 81**; при нормализации регистра и апострофа **65 из 81** ⇒ 16 глав навигация не называет вовсе |
**А настоящих глав — 81, плюс пролог, и это первое, что я ставил неверно ДВАЖДЫ.** Форма главы: римское
числительное, затем имя прописными тем же классом, затем проза другим классом. Замер: голых римских
числительных **84**, из них **81 имеет имя следом** и **3 не имеют** — все три в открывающей секции `SUNSET`,
где за номером идёт сразу проза. ⇒ **«84 главы» есть ВЫВОД прибора, а не замер книги**: собственное оглавление
книги даёт «Sunset» одной строкой и 81 строку «Chapter». Контроль, доказывающий, что прибор читал книгу, —
абзацев с классом **11 397** (счётчиком по `<p[^>]*class="…"`; другой парсер на тот же вопрос даёт 11 522 —
подписывай способ счёта рядом с числом).
**СУДЬБА ПРОЛОГА — РАЗВИЛКА, И РЕШИТЬ ЕЁ ОБЯЗАН ТЫ, А НЕ УМОЛЧАНИЕ ПРАВИЛА.** Голое числительное разрежет
`SUNSET` на три безымянных главы, а единственное имя пролога уедет в преамбулу первой из них. Варианты: **81 + 3
безымянных = 84** или **81 + 1 «Sunset» = 82**, и второй требует ТРЕТЬЕЙ формы заголовка (имя без числительного),
которой у грамматики сегодня нет. Назови выбор и довод; приёмочное число — тот, который ты назвала.
⚠ И мой первый замер дал **3** вместо 84, потому что регексп требовал `class` первым атрибутом, а у
большинства первым стоит `id`. **Отрицательный замер здесь особенно дёшев и особенно лжив — печатай
контрольную величину рядом.**
Контроль, доказывающий, что прибор читал книгу: абзацев с атрибутом класса — 11 397 (счёт регекспом
`<p[^>]*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 документов по 27 глав). Она
ломает три допущения 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`). На
заголовке С сепаратором после юнита длиной 6184 руны ингест говорит «нет», чанкер «да»; `第零章` ингест режет,
а чанкер заголовок не снимает — сырой маркер уезжает модели. Без сепаратора расхождения нет. Направление
названо в самом ряду: сведение двух предикатов к ингестовским стражам. Пин
`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`.
- ⇒ на заголовке С СЕПАРАТОРОМ после юнита (`第四章:…`) длиной 6184 руны ингест говорит `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 — отдельным пунктом.
- [ ] Числа сняты ПОСЛЕ последней правки; гейт зоны прогнан целиком, полнота — сверкой СПИСКА пакетов; всё
живое — в дереве.
- [ ] Явное **«работа завершена, править не планирую»**.
**И последнее.** Предмет пака — **кто решает, где начинается глава**. Ответ, к которому надо прийти:
тождество решает движок, потому что это факт, а не догадка; АДРЕС границы решает грамматика книги; ИМЯ берётся
у того, кто его несёт. Всё, что сверх этого, решают данные книги. Если твоё
решение где-то ставит догадку движка на место данных — оно не готово, сколько бы тестов ни было зелёными.
**Ответ, к которому пак ведёт:** тождество, СОПОСТАВЛЕННОЕ заголовку в прозе, решает движок, потому что это
факт книги, а не порог; АДРЕС границы даёт грамматика,
ИМЯ — тот, кто его несёт; всё, что сверх этого, — данные, которые ведут себя верно там, где явления нет. Решение,
ставящее догадку движка на место факта книги, не готово, сколько бы тестов ни было зелёными.

View file

@ -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`, — а РАЗРЕЗ на главы нет). ⚠ Делать в единственном окне пере-снапшота, пока платная книга одна: перекрой двигает нарезку. Пере-скоуп строк 160162 ⭐ **ЧИСЛА НА БОЕВОЙ АНГЛИЙСКОЙ КНИГЕ, замер зоны 18.09 — предмет ряда впервые получил величину.** Книга Кристоффа режется движком на **71 «главу», из которых настоящих ШЕСТЬ** (`BOOK ONE``BOOK SIX`, 140390 тыс. знаков), одна средняя и **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`, — а РАЗРЕЗ на главы нет). ⚠ Делать в единственном окне пере-снапшота, пока платная книга одна: перекрой двигает нарезку. Пере-скоуп строк 160162 ⭐ **ЧИСЛА НА БОЕВОЙ АНГЛИЙСКОЙ КНИГЕ, замер зоны 18.09 — предмет ряда впервые получил величину.** Книга Кристоффа режется движком на **71 «главу»**. ⚠ **ИСПР. 18.09 (`D39.270`): прежняя редакция писала «настоящих ШЕСТЬ, 64 крошечные» — это граница ДОКУМЕНТОВ, а не глав.** Настоящих глав по печатному оглавлению книги **81** плюс разделы `SUNSET` и `DAWN`; навигация называет 65 из них и целит в осколки оглавления (60 тел побуквенно равны ярлыку), 28 прозаических документов несут по 27 глав. Полная раскладка — таблица §1 промта `docs/BACKEND_CHAPTER_STRUCTURE_SESSION_PROMPT.md`. Прежние слова: «настоящих ШЕСТЬ (`BOOK ONE``BOOK SIX`, 140390 тыс. знаков), одна средняя и 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, посадка вне списка автора |

File diff suppressed because one or more lines are too long

View file

@ -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 документов по 27 глав), единица правила — абзац (построчно 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** |

View file

@ -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 подтверждены критиком по дереву,
два опровергнуты в деталях). Пункты 16 выше остаются как написаны; вот что в них неверно:**
- п.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 документов несут по 27 глав** ⇒ резать внутри документа эту
книгу НЕОБХОДИМО; форма ряда 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 подтверждены) · советчик — три круга, последний «ОК после пяти правок», правки подтверждены им же. ⛔ СЛОТ БЭКЕНДА ЗАНЯТ до акта закрытия этого пака.

View file

@ -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` ОТОЗВАНА тем же часом. ⚠ Урок не про полигон: **я трижды искал адресата для заказа, приоритет которого не подтверждал у владельца.** Слот зоны свободен ≠ работу зоны надо заказывать.