Issue the book-writer prompt after the refuter found eight wrong facts and a fork the owner had gated: an EPUB writer already exists in the tree and the only named corpus is not translated
This commit is contained in:
parent
e1e48acf60
commit
dac0630018
3 changed files with 187 additions and 3 deletions
183
docs/BACKEND_BOOKWRITER_PACK_SESSION_PROMPT.md
Normal file
183
docs/BACKEND_BOOKWRITER_PACK_SESSION_PROMPT.md
Normal file
|
|
@ -0,0 +1,183 @@
|
|||
# Промт: движок, пак «писатель книги» — переведённая книга становится ФАЙЛОМ
|
||||
|
||||
## 0. Какая проблема и что решит твой результат
|
||||
|
||||
Проект переводит книги и **не умеет отдать книгу**. Ни одной стороной. Движок отдаёт только поток:
|
||||
`renderExport` (`backend/cmd/tmctl/render.go:565`) печатает стабильный JSON `tm-export-v1` либо
|
||||
`--plaintext` с аудит-баннерами `=== CHAPTER N CHUNK M ===`. Греп `epub|fb2|docx` по `backend/**` минус тесты даёт **43** попадания, из них 29 в `internal/chunk/`
|
||||
`ingest.go`. ⚠ **И писатель EPUB в дереве УЖЕ ЕСТЬ** — `backend/internal/chunk/chunktest/epub.go:37-112`
|
||||
(`BuildEPUB`/`BuildEPUBAt`): настоящий OCF-контейнер, `mimetype` первым и `zip.Store`, `container.xml`,
|
||||
`content.opf` с manifest+spine, XHTML. Он ТЕСТОВЫЙ, но обратим ингесту по построению и запинен
|
||||
(`ingest_test.go:537` `TestEPUBFixtureMimetypeIsOCFConformant`). Его собственная шапка предупреждает:
|
||||
дублирование zip/OPF-строителя развело бы две копии. **Начинать с него, а не с нуля.**
|
||||
Платформа обещанные каноном ручки выдачи не монтирует, и её `export_formats` захардкожен пустым.
|
||||
|
||||
**Что решит твой результат:** переведённую книгу можно будет открыть в читалке. Сегодня цель №1 канона
|
||||
(«издательское художественное качество») не проверяется ничем на выходе: результат некуда открыть.
|
||||
Носитель — строка **236** единого бэклога, вес «блокер-очереди», пункт 1 очереди №20.
|
||||
|
||||
**Чего твой результат НЕ решает:** дверь платформы (`createExport`/`getExport`) — отдельная работа
|
||||
ПОСЛЕ живого прогона, потому что до него неизвестно, что реально кладётся в файл.
|
||||
|
||||
## 1. Зона записи и git
|
||||
|
||||
Пишешь только в `backend/`. **Не коммитишь**: дерево готовишь и передаёшь оркестратору. Канон git — в
|
||||
`CLAUDE.md`, здесь не дублируется. Чужие незакоммиченные файлы не трогать.
|
||||
|
||||
## 2. Карта чтения — ПЯТЬ позиций, дальше только по их ссылкам
|
||||
|
||||
1. `backend/internal/pipeline/export.go` — **прежде всего блок CAVEATS над `Export`**: там названы три
|
||||
состояния, которые твой файл обязан не соврать (дрейф конфига, ghost-строки, pending-юниты).
|
||||
2. `backend/cmd/tmctl/render.go:562-630` — существующий рендер и то, чем `--plaintext` НЕ годится
|
||||
в качестве книги (аудит-баннеры, флаги в скобках).
|
||||
3. `backend/internal/chunk/ingest.go` — как книга РАЗБИРАЕТСЯ из epub: писатель обязан быть обратим к
|
||||
этому чтению, иначе круг «загрузил → получил» не замыкается.
|
||||
4. `docs/architecture/12-go-style-notes.md` §0 — норматив общности: **пары языков это ДАННЫЕ**.
|
||||
5. `docs/PROGRESS.md` строка **201** (синтетический заголовок едет внутри текста юнита) — твоя развилка,
|
||||
см. §3.3.
|
||||
|
||||
## 3. Работа
|
||||
|
||||
### 3.1 Что построить (делай РОВНО так)
|
||||
|
||||
**Движковый писатель книги из `BookExport`**, вызываемый из `tmctl`. Минимум два формата: **EPUB**
|
||||
(книга для читалки) и **чистый текст** — без аудит-баннеров, без флагов в скобках, без служебных
|
||||
маркеров. Существующий `--plaintext` не трогать и не переименовывать. ⚠ Обоснование именно такое, а не обратное:
|
||||
`eval/README.md:80` говорит «`--plaintext` для глаз, дефолтный JSON для скриптов» — то есть машинная
|
||||
поверхность это JSON, и у него ДВА потребителя: полигон и **платформа** (`platform/internal/runner/`
|
||||
`engine.go:137` → `ingest/export.go` `DecodeExport`; `STACK_DECISIONS.md:376` называет его «единственным
|
||||
каналом, несущим ТЕКСТ пары»). Менять форму `tm-export-v1` — значит менять платформу из чужой зоны.
|
||||
|
||||
⛔ **Файл обязан быть ДЕТЕРМИНИРОВАН:** два прогона на одних данных дают побайтово одинаковый файл.
|
||||
EPUB — это zip, и в нём по умолчанию лежат時metки и порядок записей; если они текут, детерминизм
|
||||
проекта (цель №6) кончается на последнем шаге. Докажи прогоном, а не рассуждением.
|
||||
|
||||
### 3.2 Три состояния, о которых файл не имеет права соврать (делай РОВНО так)
|
||||
|
||||
`Export` их уже вычисляет — не изобретай заново, но и не игнорируй:
|
||||
- **`PendingUnits > 0`** — книга переведена НЕ ЦЕЛИКОМ. Файл, молча притворяющийся полным, — худший
|
||||
исход этого пака.
|
||||
- **`GhostRows > 0`** — есть строки вне текущего манифеста.
|
||||
- **`ConfigDrift == true`** — текущий конфиг рендерит не тот снапшот, что несут строки.
|
||||
|
||||
**Как именно это показать читателю — решаешь сам и аргументируешь** (отказ писать · писать с явной
|
||||
пометкой · отдельный флаг команды). Что НЕ обсуждается: молчаливого полного файла на неполной книге
|
||||
быть не может.
|
||||
|
||||
### 3.3 Синтетический заголовок — НЕ твоя развилка (делай РОВНО так)
|
||||
|
||||
Заголовок «Глава N» сегодня клеится ВНУТРЬ текста юнита — `export.go:266`, и ещё в ДВУХ точках
|
||||
`waverun.go:647` и `waverun.go:721` (третья — путь draft-only отгрузки). Инвариант, который они держат и
|
||||
который назван в самом коде: `tmctl export` и `tmctl translate` отгружают побайтово одинаковый текст.
|
||||
|
||||
⛔ **Трогать `ApplyHeading` и любую из трёх точек ЗАПРЕЩЕНО.** Дизайн глав НЕ ратифицирован (D39.122
|
||||
п.2д: `heading` манифеста — ВРЕМЕННЫЙ рендер движка), а форма для него уже назначена: строка бэклога
|
||||
**160** «Структура глав, Этап 0», гейт которой пал словом владельца 15.08 (**D39.136 п.3**) — она едет
|
||||
ОТДЕЛЬНЫМ паком с мандатом максимального качества. Строка **201** — её родня и стоит «когда-нибудь (с
|
||||
160)». Этот пак её не решает и не предвосхищает.
|
||||
|
||||
**Что делать вместо:** заголовок для оглавления брать из УЖЕ персистированного манифеста —
|
||||
`ManifestChapter.Heading` (`backend/internal/pipeline/manifest.go:108`), тот же детерминированный литерал.
|
||||
Форма `tm-export-v1` не меняется, разбирать ничего не надо, оглавление есть. Если текст юнита при этом
|
||||
начинается тем же заголовком — срезать ИЗВЕСТНЫЕ байты префикса (`ApplyHeading` — чистая склейка
|
||||
`heading + "\n\n" + text`, `chunker.go:186-192`), а не угадывать эвристикой. ⚠ Если найдёшь причину, по
|
||||
которой так нельзя, — **пинг, а не своё решение**: вопрос гейчен владельцем.
|
||||
|
||||
### 3.3-бис Метаданных книги в `BookExport` НЕТ — учти до кода
|
||||
|
||||
Структура несёт `Version`, `BookID`, `TotalUnits`, `PendingUnits`, `GhostRows`, `ConfigDrift`,
|
||||
`CurrentSnapshot`, `Chunks` — и **ни заголовка, ни языка, ни автора**. EPUB требует `dc:title`,
|
||||
`dc:language`, `dc:identifier`. Первые два достижимы из `config.Book` (`book.go:25-27`: `Title`,
|
||||
`SourceLang`, `TargetLang`); **автора в проекте нет вовсе** — источника для `dc:creator` не существует,
|
||||
и выдумывать его не надо. ⛔ `dc:language` берётся из `TargetLang`, а не литералом: пары — данные.
|
||||
**Решаешь сам:** расширять ли `BookExport` (⚠ добавление поля безопасно — платформа декодирует
|
||||
подмножеством и неизвестные поля игнорирует; ПЕРЕНОС существующего поля — нет) или брать метаданные
|
||||
мимо него.
|
||||
|
||||
### 3.4 Куда пишется файл — размечено, не додумывай
|
||||
|
||||
⚠ `tmctl` сегодня не пишет НИ ОДНОГО файла: греп `os.Create|os.WriteFile` по `cmd/tmctl/*.go` минус
|
||||
тесты пуст, всё идёт в stdout. Значит выходная поверхность — новая. **Реши и аргументируй:** флаг пути
|
||||
или stdout · поведение при существующем файле (перезапись или отказ) · один файл на книгу или на главу.
|
||||
Молча выбранная форма здесь дороже неверной: её потом читает платформенная дверь выдачи.
|
||||
|
||||
### 3.5 Границы
|
||||
|
||||
- ⛔ **Платформу не трогать вообще.** Её дверь — следующая работа, не твоя.
|
||||
- ⛔ **Формат `tm-export-v1` не менять** без явного довода: его потребляет полигон.
|
||||
- ⛔ **Пары языков — данные.** Ревью-вопрос: «заработает ли пара, которой в репо НЕТ, без правки Go?»
|
||||
Если твой писатель знает слово «Глава» или порядок имени автора — это утечка.
|
||||
- **Внешние зависимости:** EPUB это zip + XHTML, и стандартная библиотека это умеет. Новая зависимость
|
||||
ради формата — решение с доводом и строкой в `STACK_DECISIONS`, а не побочный эффект.
|
||||
|
||||
## 4. Самопроверка ИСПОЛНЕНИЕМ (без неё работа не принята)
|
||||
|
||||
- ⚠ **ДАННЫЕ: `coldrun-a` НЕ переведена — не строй на ней доказательство.** Проверено: у неё только
|
||||
волна `draft` (20 строк), финальной стадии нет ни у одного юнита, экспорт даёт **14/14 pending** и
|
||||
`CONFIG-DRIFT`. Вдобавок её конфиги несут абсолютные пути `/home/ubuntu/…` от прежней машины и
|
||||
ретайрнутые ключи, а схема БД v14 против головы v16 — `tmctl export` там падает четырьмя разными
|
||||
отказами подряд. **Годные книги с волной `edit`:** `books/gu-zhenren/minirun` (draft 20 / edit 14, схема
|
||||
v10) и `books/gu-zhenren/acceptance` (57/57, v7) — обе требуют миграции до v16. ⛔ **`books/` — отдельный
|
||||
git-репозиторий со своим origin: работай на КОПИИ в песочнице, оригиналы не мигрируй и не правь.**
|
||||
- **Файл открывается читалкой** — если есть чем. Проверено: на этой машине нет ни `calibre`, ни
|
||||
`epubcheck`, ни `java`, ни python-библиотек epub. Значит ось «издательский результат» механического
|
||||
верификатора пока не имеет: либо приноси свой (валидатор в песочнице), либо честно пиши в obstacle, что
|
||||
проверено структурно, а не читалкой. Не выдавай второе за первое.
|
||||
- **Круг замыкается:** файл, который ты написал, скорми обратно `internal/chunk/ingest.go` и покажи,
|
||||
что он разбирается. Это единственная механическая проверка, что писатель обратим чтению.
|
||||
- **Детерминизм:** два прогона → `cmp` побайтно. Покажи команду и результат.
|
||||
- **Три состояния §3.2** — по посадке на каждое: неполная книга, ghost-строка, дрейф конфига. Каждая
|
||||
обязана отработать так, как ты решил, и это видно в файле или в отказе.
|
||||
- ⛔ **Править или удалять тест ради зелени НЕДОПУСТИМО (D39.121).** Это не абстракция: любой вариант,
|
||||
трогающий заголовок, красит `backend/internal/chunk/chunker_heading_test.go:121`, и самый дешёвый
|
||||
способ вернуть зелень — правка ассерта. Несогласие с тестом — пинг, а не правка.
|
||||
- **Дифф `^func Test` — ИСПОЛНЕНИЕМ, не памятью:** покажи командой, что ни один тест не исчез.
|
||||
- **Интервальная самоверификация** (D39.121): пак длинный, поэтому в СЕРЕДИНЕ работы — проход субагента
|
||||
по готовой части против явных критериев, а не только в конце.
|
||||
- **`make battery` целиком**, не `go test`: линтер идёт ДО тестов, и на этом уже попались двое. `-race`
|
||||
обязателен.
|
||||
- **Разрешаю субагентов** (иначе дефолт харнесса тихо запретит). Модель задавай ЯВНО и знай, сколько
|
||||
их работает. Трудный вопрос — старшей модели.
|
||||
- ⚠ **Адверсариальный проход по своей готовой работе перед сдачей.** Направление: файл, молча
|
||||
притворяющийся полным; недетерминизм zip; заголовок, потерянный или задвоенный; кодировка и
|
||||
направление письма; книга из одного юнита и книга из нуля юнитов. **Пока идёт проход — дерево не
|
||||
двигается:** либо морозь, либо называй агенту коммит.
|
||||
|
||||
## 5. Оси ревью
|
||||
|
||||
**Издательский результат** (файл открывается и читается как книга) · **честность выдачи** (неполнота
|
||||
никогда не выглядит полнотой) · **детерминизм** (побайтовая воспроизводимость). Вправе заменить ось с
|
||||
аргументом.
|
||||
|
||||
## 6. Записка-план и комплектность
|
||||
|
||||
До кода — короткая записка-план в `docs/PROGRESS.md`, секция «Бэкенд»: что берёшь, что не берёшь, чем
|
||||
докажешь. Перед сдачей — механическая сверка состава против §3 таблицей: пункт → сделано/нет → чем
|
||||
доказано. Пропуск подписывается пропуском. **Последний абзац отчёта оказался планом или обещанием?
|
||||
Сделай сейчас.**
|
||||
|
||||
## 7. Канал вопросов и право отказаться
|
||||
|
||||
Конфликт промта с кодом или доками — **пинг через владельца, не интерпретация**. Есть право сказать
|
||||
«этого делать не надо» с аргументом.
|
||||
|
||||
## 8. Заявление = команда
|
||||
|
||||
Любое число и любая категорика — **с командой, которой получены**. Приёмка пере-ранит: клейм без
|
||||
пере-прогона записывается как «со слов сессии».
|
||||
|
||||
## 9. Эхо-протокол старта
|
||||
|
||||
ДО первой правки — ≤10 строк: **скоуп / инварианты / чего не делаешь**. Отправь первым действием по
|
||||
адресу оркестратора из `/tmp/textmachine-channel` (механизм — `CLAUDE.md`; впиши туда СВОЙ блок первым
|
||||
делом). **Канала нет ⇒ НЕ искать**: вопрос секцией в отчёт, работа продолжается.
|
||||
|
||||
## 10. Obstacle reporting
|
||||
|
||||
Обязательная секция: **что НЕ удалось и что осталось непроверенным**. Пустой не бывает. Три исхода:
|
||||
«подтверждено» / «опровергнуто» / **«не проверено»** — третье не сваливать во второе.
|
||||
|
||||
## 11. Журнал
|
||||
|
||||
Итоги и вопросы — `docs/PROGRESS.md`, секция «Бэкенд» (это единственное исключение из «`docs/` — зона
|
||||
оркестратора»).
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -22,7 +22,7 @@
|
|||
| Роль | Активный промт | Статус |
|
||||
|---|---|---|
|
||||
| Оркестратор | [ORCHESTRATOR_SESSION_PROMPT.md](ORCHESTRATOR_SESSION_PROMPT.md) | роль и нормы; счётчик роли — CURRENT-STATE |
|
||||
| Бэкенд | активного НЕТ | пак «деньги» ПРИНЯТ И ЗАЛЕНДЖЕН 29.08 (**D39.170**): потолок ОБЪЁМА оплаченной работы + читающий путь `status` сворачивает банк, поэтому смета доезжает до покупателя ДО покупки. Промт отработан — `archive/prompts/`. ⚠ Следующий заказ уже назван строкой **232** (ось отгрузки на `once_key`), проводка `--max-units` в платформу ГЕЙЧЕНА |
|
||||
| Бэкенд | [BACKEND_BOOKWRITER_PACK_SESSION_PROMPT.md](BACKEND_BOOKWRITER_PACK_SESSION_PROMPT.md) | **НАПИСАН, ждёт запуска владельцем.** Пак «писатель книги» — строка **236**, единственный блокер очереди: переведённую книгу нельзя отдать файлом ни одной стороной. Оба рубежа пройдены; опровергатель нашёл **восемь неверных фактов и гейченную развилку**, всё применено — в том числе что EPUB-писатель в дереве УЖЕ ЕСТЬ (`chunktest/epub.go`), что `coldrun-a` не переведена и негодна как база, и что заголовок глав трогать НЕЛЬЗЯ (гейт строки 160, D39.136 п.3) |
|
||||
| Платформа | активного НЕТ | пак `sqlc` ПРИНЯТ И ЗАЛЕНДЖЕН 29.08 (**D39.172**): 40 запросов на типизированный слой, пин 1.31.1, `sqlc diff` в `make check`. ⚠ Решение принято НЕ доводом покрытия (3 из 42), а шестью ВЫЖИВШИМИ мутациями: `sqlgate` не видит Go-сторону вызова. Промт отработан — `archive/prompts/`. Открыто строками: `Touch` без проверки затронутых строк · `observe.go` неконвертируем |
|
||||
| Полигон | [POLYGON_EXP2223_REDO_SESSION_PROMPT.md](POLYGON_EXP2223_REDO_SESSION_PROMPT.md) (отложенный — [POLYGON_PACKAGE4_SESSION_PROMPT.md](POLYGON_PACKAGE4_SESSION_PROMPT.md), строка 85) | фаза Д ИДЁТ; ⚠ живой носитель курса — в `eval/dovodka/`, какой именно называет зона (⚠ [POLYGON_PHASE_D_HANDOFF.md](POLYGON_PHASE_D_HANDOFF.md) — перекрытый снимок, читать не как курс) |
|
||||
| Фронт | активного НЕТ | **ЗОНА ЗАМОРОЖЕНА** (D39.136 п.2 + D39.147: разморозка отдельным словом владельца, не привязана к P7); перечень первого касания — в зонном журнале |
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue