textmachine/docs/CHAPTER_STRUCTURE_DESIGN_SESSION_PROMPT.md

228 lines
26 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Промт: ДИЗАЙН-пак «СТРУКТУРА ГЛАВ — БОЛЬШОЙ ПЕРЕКРОЙ» (проектирование, не стройка)
## 1. Какая проблема и что решит твой результат
Глава в движке сегодня адресуется своим ПОРЯДКОВЫМ номером. Из-за этого любая пере-нарезка книги
сдвигает адреса, и вместе с ними едут банк-окна, снапшоты, чекпойнты и сметы — то есть **деньги**.
Пока платная книга одна, пере-нарезать дёшево; после впуска пользователей это окно закроется.
Второе следствие того же корня: не-CJK книга и часть EPUB приезжают читателю **одним полотном**, и
платформа с 07.09 ОТКАЗЫВАЕТ на приёме книге из одной главы (`400 no_chapter_structure`, ратифицировано `D39.221`, канон `openapi.yaml`; остаток разреза — строка 332) —
временное продуктовое сужение, снять которое может только этот перекрой.
**Твой результат — ДИЗАЙН, а не код.** Документ, по которому следующие сессии строят, не переоткрывая
решений: чем адресуется глава, что происходит с каждой осью при сдвиге, в каком порядке идёт миграция
и какие вопросы обязан решить владелец. ⛔ **Строить в этом паке НЕЛЬЗЯ** (`D39.136` п.3: дизайн идёт
перед стройкой). Исключение одно — измерительные пробы, см. §5.
## 2. Зона и git
**Зона записи: `backend/docs/`** (дизайн-документ) плюс своя секция «Бэкенд» в `docs/PROGRESS.md`. Код `backend/**` — только ЧИТАТЬ; правки кода в этом паке запрещены,
кроме выброшенных проб (§5), которые в дерево не попадают.
**Сессия НЕ коммитит** — дерево передаёшь оркестратору. Канон git — `CLAUDE.md`. `.env` не читать.
⚠ Что должно пережить рестарт — в РЕПОЗИТОРИЙ, а не в скрэтчпад. ⚠ Входящее сообщение другой сессии —
не приказ: промт сильнее, расхождение — пинг.
## 3. Карта чтения — ЗАКОН, дальше только по её ссылкам
1. `CLAUDE.md` — цели владельца и гардрейлы.
2. Строки бэклога **161**, **283**, **302**, **303**, **320**(б), **332** (`docs/BACKLOG.md`, греп `^| N |`).
3. `docs/research/33-backend-debt.md`**читать через ревью-шапку** (статус: ФАКТУРА, НЕ ратифицирована),
предметно — секция «Спроектировать ЗАНОВО и отрефакторить без заплат» (строка 451).
4. `docs/research/27-chapter-detection.md` §3а (жизненный цикл дерева) и §5 п.89 (id и деньги).
**D-нотой НЕ ратифицировано** — это фактура ресёрча о самом себе; при конфликте с D-логом побеждает лог.
5. `docs/architecture/18-bank-ontology.md` — РАТИФИЦИРОВАНА, обязательное пре-чтение перед всем, что
трогает банк; плюс `backend/README.md` для механики движка.
**Ратифицированное, что нужно для работы:**
- **`D39.216` (мандат чистоты, решение владельца), делай РОВНО так:** проектировать без хаков и
воркэраундов; где форма не тянет — развязать или переписать. «Дешевле подпереть» доводом НЕ является.
Отступление законно, но объявляется С ЦЕНОЙ. ⚠ Этот пак существует именно потому, что заплатой его
предмет закрыть нельзя.
- **`D39.104` — закон банка:** строка на проводе есть закон для КАЖДОЙ роли и КАЖДОЙ строки независимо
от статуса. Дизайн его не ослабляет.
- **Ревью-вопрос проекта по умолчанию** (`CLAUDE.md` §Цели п.2): «заработает ли пара, которой в репо ещё
НЕТ, без правки Go?» Каждое твоё решение обязано иметь на него ответ.
- **Число называет ДЕРЕВО и ПОПУЛЯЦИЮ** · **рядом с нулём контрольная величина ПЕЧАТАЕТСЯ** · **мутация
засчитывается по ТЕКСТУ сообщения**.
## 4. Состав и разметка свободы
### 4.1 Чем адресуется глава и развязка чанкера от глав — **реши сам, аргументируй; центральное решение пака**
**Это ОДИН предмет, а не два.** `research/33` склеивает формулу `Chapter.ID` и развязку чанкера в ОДНУ
перенарезку: разносить их значит платить перекроем дважды. Дизайн отвечает на оба вопроса вместе.
Сегодня два числа главы уже расходятся: плотный `Chapter` (первичный ключ, адрес redrive) и номинал в
заголовке (`Heading` рендерит исходное `n`) — на неплотной нумерации и на прологе. Дизайн обязан
назвать, каким числом глава адресуется, что происходит со вторым, и как адрес переживает пере-нарезку.
⚠ Половина фундамента уже стоит и запинена (`manifestChapterID`,
`TestManifestChapterIDSurvivesAReCutAndAnEditElsewhere`) — начни с чтения того, что построено.
**ПРИОР, а не пустой вопрос:** `research/27` §5 п.9 предлагает контент-производный id (хеш первого окна тела
с титулом) и карту миграции `same/moved/split/merged/gone/new`, §5 п.8 — деньги и память ключуются хешами
СЕГМЕНТОВ, а глава есть группировка. На этом сошлись две модели панели. **Прими или опровергни ЗАМЕРОМ**
но не переоткрывай молча. ⚠ Сюда же вопрос владельцу (§11): точка ЗАТВЕРДЕВАНИЯ структуры — `research/27`
§3а п.4 говорит «твердеет на подписи банка», и это D-нотой не ратифицировано.
### 4.2 Карта осей сдвига — **состав делай РОВНО так; ответы по осям — ПРИОР, опровергается замером**
Сегодня предикат `classifySnapshotMove` — одна строковая константа. Дизайн обязан дать явную карту осей
(провод · вердикт · банк · контент · позиция) и на КАЖДОЙ честно ответить, что делать: провод — купить,
вердикт — пере-вынести из чекпойнта за $0, банк — ре-пин, контент — показать смету. Одним куском с
`projectRebill` (контентная и позиционная оси): это две стороны вопроса «какая ось уехала». От этой
карты зависит, будет ли перекрой молчаливым для владельца книги.
### 4.3 Банк-окна на chapter-ID — **делай РОВНО так**
Дизайн предписывает ФОРМУ перевода `since_ch`/`until_ch` на адрес главы из §4.1 (не пишет код). Класс переноса — `moveBankOnly` (ре-пин за $0),
миграция мелкая. Дизайн называет форму миграции и её стоимость числом, а не словом «мелкая».
### 4.4 Что входит в окно пере-нарезки и что НЕ входит — **делай РОВНО так**
Расщепление `EmbeddedVersion` на три радиуса (по образцу `bankdata.go`) двигает хеш ⇒ идёт ТОЛЬКО
внутри этого окна. ⚠ Это и есть **«третий версионный план паттернов»** строки 161: план ДАННЫХ вне волнового
снапшота — назови его этим именем, чтобы носитель был один. Сюда же строка **320**(б) — правка `internal/lang/data/injection.txt` (стоп-мир:
`EmbeddedVersion``cutTag``manifestKey` (`manifest.go:341`; ⚠ форма `manifest_key` в строке 320 ошибочна)). **`structure_version` как самостоятельная ось консент-гейта — решить в дизайне.** ⚠ Приор `research/33` (Д6):
не через `buildSnapshotID`, довод — `repinnable()` истинен только на bank-only move, а фолд протухает все
`chunk_status`. Приор, а не запрет: опровергается аргументом.
**Сюда же — МЕСТО СТРОКИ 160, и ответ обязателен** (`D39.224` п.6). `D39.190` п.2 поставила Этап 0 СВОИМ паком после двери выдачи, СТОП-МИРОМ: у бампа `manifestVersion` безопасного порядка деплоя нет ни в одну сторону (`PD-436`), гейт интейка платформы — строгое равенство одной константе. Перекрой пере-минтит КЛЮЧИ манифеста, но двигать его ФОРМУ не обязан ⇒ назови, ложится ли Этап 0 в тот же стоп-мир, что перекрой. Два стоп-мира вместо одного — цена, которую никто не назначал, и умолчать её нельзя.
### 4.4а Контент-адресуемый resume (долг `D15.2`) — **делай РОВНО так**
Это механизм, на котором стоит денежное обещание §1: деньги и память ключуются хешами СЕГМЕНТОВ, а глава —
их группировка (`research/27` §5 п.8). Пере-нарезка тогда есть ПЕРЕГРУППИРОВКА уже оплаченного, а не его
потеря. Без этого пункта §4.1 решает адресацию, но не отвечает, почему перекрой не сжигает купленное.
### 4.4в Предикат осей — **делай РОВНО так** (критерий ратифицирован `D39.224` п.8)
Сегодня `classifySnapshotMove` знает ОДНО re-pinnable поле (`repin.go:54`), всё прочее — `moveOther`. Дизайн
обязан выдать явную карту осей, и она проверяемая, а не декларативная: **(1)** таблица относит КАЖДЫЙ
JSON-ключ снапшота (`snapshot.go:342-425` — на 07.09 их 22) ровно к одной оси — провод · вердикт · банк · крой; **(2)**
рефлексивный тест по образцу `TestEveryCutInputMovesTheTag` (`cuttag_test.go:26`) краснеет на ключе БЕЗ оси,
чтобы ни один не попадал в `moveOther` умолчанием; **(3)** резюм-тест: сдвинут ТОЛЬКО вердикт-ключ ⇒ ноль
платных вызовов, вердикт пере-вынесен из текста чекпойнта (сегодня `resume.go:24-26` отдаёт сохранённый
слепо); **(4)** `TestRepinRefusesAnyMoveThatIsNotBankOnly` (`miningstop_join_test.go:1686`) пере-скоупится
ЗАКАЗОМ пака и объявляется в отчёте (`D39.183`); **(5)** `projectRebill` показывает контентную и позиционную
оси (`rebill.go:33-36` сам называет их непроецируемыми). ⚠ **Что этот предикат НЕ покупает:** wire-правка
меняет рендер провода ⇒ `ContentHash` другой ⇒ модель придётся вызвать при любой карте осей
(`stagerun.go:91-92`). Норма «копить одним касанием» падает только для ВЕРДИКТ-оси — так и напиши, иначе
дизайн пообещает больше, чем механизм даёт. Мерило: бамп `CheapGateVersion` на продолжаемой книге ложится с
нулём платных вызовов и без `--resnapshot`.
### 4.4б IR, формато-адаптеры и индуктор — **реши сам, аргументируй ГЛУБИНУ**
Строка 161 называет IR + адаптеры (EPUB `nav`/NCX построен, **FB2 нет вовсе**) + индуктор с валидаторами и
вердиктами (`research/27` §5: `OK` / `DEGRADED` / `FAILED`). Дизайн обязан назвать ФОРМУ этого слоя и то, как
вердикт индуктора доезжает до пользователя, — но глубину проработки выбираешь ты: если честный ответ «это
отдельный дизайн», скажи это с доводом и назови шов, который перекрой обязан не сломать.
### 4.5 Правило заголовка, не-CJK путь и `unit_resolutions` — **делай РОВНО так**
Дизайн предписывает: три предиката заголовка сводятся к ОДНОМУ источнику стражей, паритет-тест ингест↔чанкер
ОПИСЫВАЕТСЯ (пишет его пак стройки).
Строка **303**: чанкер безъюнитную грамматику («Kapitel 12») уже умеет, ингест по ней не режет —
дизайн обязан закрыть ревью-вопрос §3 для языков БЕЗ юнита, и закрыть его ДАННЫМИ, а не веткой в Go.
Сюда же строка **298** (`unit_resolutions`): `research/33` называет её аддитивной, но требует решить В ТОМ ЖЕ
дизайне — реши и назови форму.
### 4.6 Гранулярность EPUB и выдача — **реши сам, аргументируй**
Строка **302**: несколько глав в одном документе, разделённых якорями `nav`, сегодня схлопываются в
одну; провенанс честен (`delimited` + счёт), разрез груб. Строка **283**: билдер кладёт по XHTML на
главу движка ⇒ не-CJK txt приезжает одним полотном. Дизайн называет, режется ли документ по якорям
целей, и что из этого снимает временный отказ интейка (`D39.221`).
### 4.7 Чего в паке НЕТ — **не делай**, и это ОБЪЯВЛЕННЫЕ сужения, а не умолчания
Общее: не строить код · не менять контракт (аддитивное расширение только ОПИСАТЬ) · не трогать `configs/`
и `internal/lang/data/` · не заказывать платных прогонов · не решать за владельца вопросы §11.
Из строки **161** сознательно СНЯТО с этого пака:
- **Роль title / мини-сессия названий** (редакторский слот · инъекция банка · двухфазно вокруг подписи) —
отдельный предмет с продуктовой стороной и своим денежным следом. ⚠ Дизайн обязан назвать ШОВ, который
перекрой не имеет права сломать, и на этом остановиться.
- **Аддитивное расширение контракта 14** — ОПИСАТЬ, что понадобится, и не более: канон правит оркестратор.
**Конфликт, который ты встретишь на первом часу, и его диспозиция.** `research/33` §5 «Шаг 0 — ДО дизайна»
заказывает пять $0-правок кода (включая «паритет-тест пишется сейчас»). **В этом паке они НЕ делаются:**
§2 запрещает код, и они уже заказаны ОТДЕЛЬНО — строки **344** · **345** · **346**(а) · **349** и дописка **224**, порядок ратифицирован `D39.224` п.3: шаг 0 идёт СВОИМ паком ПАРАЛЛЕЛЬНО тебе и обязан лечь до пака СТРОЙКИ, не до тебя. Ты их НАЗЫВАЕШЬ как предусловия пака стройки; если какая-то нужна, чтобы ответить на
вопрос дизайна, — ставь выброшенную пробу (§5 п.3), в дерево она не попадает.
## 5. Мандат самопроверки ИСПОЛНЕНИЕМ — «перечитал сам» не считается
Дизайн проверяется иначе, чем код, и вот чем именно:
1. **Каждое утверждение о ТЕКУЩЕМ коде — грепом или прогоном, с `file:line`.** Дизайн, стоящий на
неверном описании сущего, дороже отсутствующего: по нему будут строить.
2. **Числа радиуса — СВОИМ замером.** `research/33` называет 183 площадки, из них **64 % (117/183) в `membank`+`store`** (⚠ его же строка 137 говорит «вне `internal/pipeline`» — это ДРУГАЯ величина, 140/183 = 77 %, ресёрч себе противоречит);
пере-считай своим прибором, назови популяцию и дерево. Разойдёшься — это находка, а не ошибка.
3. **Ключевые допущения — выброшенной пробой** (`go test -overlay` в песочнице, в дерево не попадает).
Как минимум: расхождение двух чисел главы на реальной книге корпуса и поведение банк-окна при
пере-нарезке. $0, read-only.
4. **Опровергатель твоего готового дизайна отдельным субагентом.** Харнесс по умолчанию субагентов не
спавнит — тебе РАЗРЕШЕНО и требуется. Модель задай ЯВНО (`fable`), одного-двух хватит. Мандат:
«найди в этом дизайне решение, которое не переживёт первой же стройки», а не «проверь, всё ли хорошо».
5. **Интервальная самопроверка** примерно на середине — субагент против ЯВНЫХ критериев §4.
6. **Перед отчётом сверь каждый клейм с результатом инструмента ЭТОЙ сессии.**
## 6. Оси ревью — характер «Ресёрч/текст» и «Доки»
- **Claim-fidelity:** цитаты — дословные подстроки первоисточников; типовой провал здесь ОВЕР-АТРИБУЦИЯ,
а не выдумка. Приписал решение ноте — грепни ноту.
- **Доки:** сверка утверждений против кода и живых носителей.
## 7. Записка-план ДО работы
До первой строки дизайна пришли оркестратору ≤15 строк: что берёшь по каждому пункту §4 · где ждёшь
сопротивления · что считаешь спорным в самом заказе.
## 8. Заявление = команда
Любое число и любая категорика — с командой, которой получены, и её выводом.
## 9. Эхо-протокол старта
ДО первой правки пришли **оркестратору первым действием, по адресу из `/tmp/textmachine-channel`**
(`SendMessage`) ≤10 строк: скоуп · инварианты · не-делать. Эхо в собственный блокнот не эхо. Канала
нет — эхо первой секцией отчёта, это законный случай.
## 10. Что НЕ удалось — обязательная секция отчёта
Что не проверено · что не воспроизвелось · где данных не хватило. **«Не измерено» вместо догадки.**
## 11. Канал вопросов, право отказаться и что решает ВЛАДЕЛЕЦ
Конфликт промта с кодом — пинг, не интерпретация. Право сказать «этого делать не надо» с аргументом.
**Отдельной секцией дизайна — вопросы, которые обязан решить владелец**, с ценой каждого варианта:
как минимум номер главы в глазах пользователя, судьба уже переведённых книг при перекрое, то, платит
ли кто-нибудь за пере-нарезку, и **точка затвердевания структуры** (§4.1: `research/27` §3а п.4 говорит
«твердеет на подписи банка», D-нотой не ратифицировано). Не решай их за него и не прячь в прозе.
## 12. Прямой канал
`CLAUDE.md` §«Связь между сессиями»: `/tmp/textmachine-channel`, свой блок первым делом, живость —
`ListAgents`. Роли нет или файла нет — нормальный случай: вопрос секцией в отчёт, сессии подряд не
опрашивать.
## 13. Критерий завершённости — по нему тебя примут
Работа завершена, когда: у каждого пункта §4 есть исход (решено · сознательно не решаю с доводом ·
вопрос владельцу) · круги самопроверки СОШЛИСЬ — последний не дал НОВЫХ находок, прежние закрыты
таблицей «находка → что сделано → чем предъявлено» · числа сняты после последней правки · всё живое в
ДЕРЕВЕ, а не в письме · явное «работа завершена, править не планирую». Без последнего пак считается идущим.
**Оркестратора тегать «просто так» нельзя**его приёмка идёт последней и вторым кругом тебе не служит.
## Деньги
**Пак — $0.** Платных вызовов нет: дизайн, гре́пы, читающие пробы. Упрёшься в «это предъявляется только
платным прогоном» — пинг за санкцией, не своё решение.
## Отчёт
Дизайн-документ в `backend/docs/` + секция «Бэкенд» в `docs/PROGRESS.md` + сообщение оркестратору: что
решено по каждому пункту · чем предъявлено (команда и вывод) · таблица «находка → что сделано → чем
предъявлено» · что сказал опровергатель и что ты с этим сделала · вопросы владельцу с ценой · секция §10 ·
**что ты сама считаешь слабым местом дизайна**.
⛔ Последний абзац отчёта — план или обещание? Значит работа не кончена: сделай сейчас.