textmachine/CLAUDE.md

91 lines
22 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.

# TextMachine — контекст для Claude-сессий
> ⚠ **В этом проекте нейросети делают ВСЁ: пишут код, ведут документацию, принимают решения и правят их.**
> Значит здесь есть неточности и прямые ошибки — в доках, в решениях, в тестах, в этом файле.
> **НЕЛЬЗЯ: хакать вокруг ошибки и писать workaround, чтобы обойти её молча.**
> Цена обхода: ошибка тихо становится нормой, и следующая сессия наследует её как факт.
Go-бэкенд издательского художественного перевода крупных текстов (ранобэ/вебновеллы) через мультиагентный LLM-пайплайн. **Пары языков — ДАННЫЕ, не код:** движок мультиязычный по построению, «бэкенд только под русский» — объявленная АНТИЦЕЛЬ (`architecture/09-target-architecture.md` §0.1). Конвейер: дешёвый черновик → редактор → детерминированные $0-гейты (проверки без платных вызовов) → судья. Сегодня боевая пара zh→ru; любая другая, включая не-ru цель, — вопрос данных, langpack'а и замера, а не переделки архитектуры. ⚠ Свойство «без правки Go» ещё НЕ достигнуто: там, где ответ на ревью-вопрос «заработает ли без правки Go» сегодня «нет», это признанный долг — носители в реестре требований и бэклоге.
## Цели и мерило (канон владельца — каждое решение сверяется с этим)
1. **Продукт:** издательское художественное качество перевода больших текстов — победить translationese; консистентные термины/голоса на всю книгу; чувствительный контент с учётом цензуры провайдеров.
2. **Мультиязычность:** движок ОДИН и общий; языко-/пара-/книго-специфика легитимна, но живёт в ДАННЫХ и отдельных модулях, встраиваемых архитектурно чисто (langpacks · пар-промпты · сид/бриф), и разрабатывается отдельно от ядра. Ревью-вопрос по умолчанию: «заработает ли пара, которой в репо ещё НЕТ, без правки Go?»
3. **Чистая архитектура:** бэкенд легко писать и поддерживать; механизм строится только там, где несёт качество/деньги — не ради галочки трекера.
4. **Современные подходы и харнесс-превосходство:** пайплайн и транспорт на уровне или впереди конкурентных харнесс-решений (калибровка — research/2122); эмпирика решает — мерить, не верить.
5. **Экономика:** низкий COGS на дешёвых моделях с адресными дорогими вызовами; деньги видимы с первого вызова (телеметрия · потолки · явное согласие на пере-оплату).
6. **Детерминизм:** воспроизводимый прогон (снапшоты · банк памяти · golden) — повторение без сюрпризов и тихих перепокупок.
## Владелец — контекст для разговора
Язык бэкенда выбран по удобству агентной разработки, а не по опыту владельца. Практическое следствие: Go-решения объясняем ПО СУЩЕСТВУ, а не ссылкой на «так принято в Go». Разговор и документация — по-русски, код и комментарии — по-английски (`architecture/12-go-style-notes` §1). Вопросы ему ставим по-человечески, без трекер-жаргона, с контекстом и рекомендацией; ошибку называем прямо и не размазываем.
**Долговечное знание живёт в репозитории, а не в авто-памяти:** память грузится в контекст КАЖДОЙ сессии и не видна в ревью.
## Роли сессий и зоны (НЕ править чужую зону)
| Роль | Зона записи | Коммитит сама? | Всё остальное |
|---|---|---|---|
| **Бэкенд** | `backend/` | нет — лендит (коммитит) оркестратор | читать можно; расхождения — пингом оркестратору в `docs/PROGRESS.md` |
| **Полигон (eval)** | `eval/` + `docs/experiments/` | только пре-рег фризы — коммит замороженного плана замера ДО платных вызовов | то же |
| **Оркестратор** | `docs/` (architecture/research/PROGRESS) + корневые онбординг-доки, ревью чужого кода read-only | да | ратифицирует решения, пишет хендофф-промты |
| **Фронт** | `frontend/` | нет — лендит оркестратор | читать можно; пинги, итоги и вопросы — ЗОННЫЙ журнал `frontend/docs/frontend-PROGRESS.md` (решение владельца; в `docs/PROGRESS.md` фронт НЕ пишет), туда же пишет и оркестратор; продуктовые требования — `docs/product-requirements.md` |
| **Платформа** | `platform/` (SaaS control plane: пользователи/квоты/очередь/HTTP; движок дёргает процессами, D39.81) | нет — лендит оркестратор | читать можно; пинги и итоги — ЗОННЫЙ журнал `platform/docs/platform-PROGRESS.md` (решение владельца), в `docs/PROGRESS.md` не пишет |
Координация — журнал `docs/PROGRESS.md` (секции «Бэкенд»/«Полигон»; сверху CURRENT-STATE). Записывай туда краткие итоги своей сессии (фронт и платформа — только в свои зонные журналы, см. таблицу выше). ⚠ Это ЕДИНСТВЕННОЕ исключение из «`docs/` — зона оркестратора»: бэкенд и полигон пишут в СВОИ секции этого журнала (полигон — ещё и в `docs/experiments/`), всё прочее в `docs/` правит только оркестратор. Закрытые хроники вынесены в слайсы `docs/archive/PROGRESS-*.md`НЕ читать при онбординге, только по конкретной ссылке. Параллельные сессии — норма: чужие незакоммиченные файлы в дереве не трогать; сессия считается ЖИВОЙ, пока владелец не сказал обратное.
**НОВЫЙ ПАК — НОВОЙ СЕССИИ.** Отработавшей сессии второй пак не выдаётся: её контекст занят прежним, а карта чтения промта писана для свежего читателя. Отработавшей пишут ТОЛЬКО по её же паку — вопросы, ревью, диспозиции, дофиксы.
**Связь между сессиями — файл `/tmp/textmachine-channel`.** Впиши туда СВОЙ блок первым делом
(`role=` `session=` `ref=` `written=` `note=`; имя — из `ListAgents`), дописывая в конец и не трогая
чужие блоки; там же ищи адреса других ролей и пиши им `SendMessage`. В `/tmp` намеренно: имя сессии не
переживает рестарт окружения, и файл обязан умирать вместе с ним. ⚠ **Нужной роли в файле нет, файла
нет или имя не отвечает ⇒ КАНАЛА НЕТ, и это НОРМАЛЬНЫЙ случай: НЕ опрашивай сессии подряд.** Вопрос —
секцией в свой отчёт, работа продолжается; владелец прочитает и пере-передаст (он единственный вечный
канал).
## Источники истины
**Приоритет — три различения, они разрешают все реальные конфликты:**
1. **Журнал решений `docs/architecture/05-decisions-log.md` бьёт всё.** Ратифицированный контракт; при конфликте с любым доком побеждает он.
2. **Ратифицированное бьёт фактуру ресёрчей.** Отчёт может быть опровергнут нотой и об этом не знать.
3. **Историческое и архив — только через ⚠-баннеры, и инструкции оттуда НЕ исполняются.**
**Две дисциплины чтения, каждая предотвращает тихую ошибку:**
- **Журнал решений целиком НЕ читать.** Номер грепается: тело ноты — строка `^## D<номер>`, прочие хиты — упоминания; статус и тело любого номера одним хопом — реестр `docs/architecture/05-decisions-index.md`.
- **Баннер прежде содержимого.** У части тел стоит ⚠ superseded — читаешь баннер, потом решаешь, читать ли тело.
Где что лежит — карта `docs/README.md`.
## Гардрейлы (жёсткие)
- **НИКОГДА не читать `.env`** — там ключи.
- **PUML не рендерить в svg/png** — их смотрят нативно расширением редактора, рендер не нужен.
- **Коммиты**: английский, одно предложение ≤30 слов, без Co-Authored-By. `.claude/settings.local.json` НЕ коммитить (ломает пермишены).
- **Провайдерские ловушки живут в `docs/experiments/00-provider-quirks.md` — читать ПЕРЕД правкой адаптеров и вызовов; здесь их копий нет.** Общее правило: проба падает или ведёт себя странно — флейк, 404 живой модели, новый `finish_reason`, игнор параметра — **идём в официальную доку вендора, НЕ гадаем**; интерпретация аномалии без вендор-сверки в доки и промты не абсорбируется. Слаги моделей не менять без live-фактчека; «слаг живой» ≠ «модель та же».
- Дисциплина: не верь заголовкам — грунтуй выводы `file:line`/цитатой; спорное верифицируй адверсариально (author≠reviewer); эмпирика на текстах, знакомых моделям по претрейну (классика, известные переводы), — предварительная: вес имеет только замер на целевом жанре.
- **Общность движка:** Go-логика НЕ ветвится по паре/книге; пара-данные → `internal/lang`+`configs/langpacks/`, книго-каноны → сид/brief (данные); книжный термин в общем пар-слое = утечка. Тест-данные пары легитимны. Норматив (только больные места): `docs/architecture/12-go-style-notes.md`. Ревью-вопрос по умолчанию: «заработает ли на паре, которой в репо ещё НЕТ, без правки Go?»
- **При компакции/сжатии контекста ВСЕГДА сохранять:** список изменённых файлов · незакрытые находки ревью и их диспозиции · обязательства и открытые вопросы сессии · команды тестов (D39.121).
- **Тесты и гейты не подгонять под зелень:** править или удалять тест/голден/гейт, чтобы он прошёл, — НЕДОПУСТИМО; несогласие с тестом — вопрос оркестратору пингом, не правка (D39.121).
- **Мандат самопроверки в промтах сессий (обязателен, решение владельца):** промты полигон-сессий — и вообще любых пишущих код / запросы к моделям — ДОЛЖНЫ явно требовать ревью ИСПОЛНЕНИЕМ: своего кода + сформированных запросов к моделям + полученных результатов. Сессии регулярно ошибаются и багуют, и это искажает результат; **самоотчёт «проверено» без исполнения регулярно оказывается ложным и стоит денег**. Бэкенд-промты — явный бэкенд-ревью после кода (обычно отрабатывает по опыту, но требовать явно). Пост-хок адверсариальная верификация оркестратора при лендинге — второй рубеж, НЕ замена самопроверки.
**Исполнения МАЛО: промт ОБЯЗАН заказать и ШИРОКИЙ адверсариальный проход по СВОЕЙ готовой работе** — несколько линз, мандат «найди, где я неправ», каждая находка с траекторией и `file:line`. Не «разрешён», а ЗАКАЗАН. Основание — замер 28.08: пак, где сессия прошлась так по себе, дал шесть настоящих дефектов, и ЧЕТЫРЕ из них внёс сам этот же пак; приёмка оркестратора их бы не нашла — она не знает, что и зачем пак трогал. Пак, где такой проход НЕ был заказан, сдался с одной узкой проверкой.
**Бюджет Fable 5 — не больше ОДНОГО агента ЛИБО одной подсессии воркфлоу, и только на самую тяжёлую линзу** (решение владельца 28.08); остальным линзам — модели попроще.
- **Git-координация мультисессий:**
- **Коммитит только оркестратор.** Сессии зон — бэкенд, полигон, фронт, платформа — не коммитят: своё дерево готовят и передают на лендинг (исключение: пре-рег фризы полигона). Чужую зону не трогает НИКТО.
- **Форма коммита — ТОЛЬКО с явным списком путей: `git commit -- <путь> <путь>`.** Причина механическая: голый `git commit` уносит **ВЕСЬ индекс**, включая чужие застейдженные файлы, и чужая работа уезжает под твоим сообщением. Pathspec-форма индекс не трогает.
- **НИКОГДА `git add -A` / `git add .` / `git commit -a`** — только явные пути.
- **Перед каждым коммитом:** `git status` (опознать ЧУЖОЕ) и `git diff --cached --name-only`. Увидел в индексе путь вне своей зоны — **не коммить его и не «прибирать»**: снимай не чужое из индекса, а свою задачу — коммить pathspec-формой.
- **Не оставляй свои файлы застейдженными** между операциями: пока они в индексе, их может унести чужой коммит. Стейдж и коммит — одной командой.
- **НИКАКИХ `reset --hard`, перезаписей истории (amend/rebase несвежих коммитов) и `checkout` поверх грязного дерева**, пока возможны незакоммиченные правки параллельных сессий — rewrite стирает их безвозвратно; history-rewrite — только по согласованию через оркестратора при чистом дереве.
- **Чужое уже уехало в твой коммит?** Историю НЕ переписывать — сообщить владельцу/оркестратору; содержимое при этом цело, теряется только атрибуция.
- Никогда не коммитить В ЭТОТ репозиторий: `START_PROMT.MD` (файл владельца) · `.claude/settings.local.json` · книгу и производные. ⚠ С 24.08 книги лежат в `<репозиторий>/books` и версионируются ОТДЕЛЬНЫМ git-репозиторием со своим origin; внешний держит `/books/` в `.gitignore`. Следствия: `git status` внешнего репо правки книг НЕ показывает (смотреть `git -C books status`), а `clean -xdf` снёс бы каталог вместе с его историей.
## Онбординг новой сессии (порядок чтения)
**Развилка ПЕРВАЯ, до всего остального — есть ли у тебя хендофф-промт (файл задания, выданный оркестратором).**
- **С промтом:** этот файл → СВОЙ промт; его карта чтения (≤5 позиций) — ЗАКОН, дальше только по её ссылкам. README, CURRENT-STATE и голову журнала решений читать НЕ нужно, ЕСЛИ карта промта их не называет (у ролевого промта оркестратора называет — там его номер и очередь): ратифицированное вложено в тело промта, остальное берётся грепом по мере вопросов.
- **Без промта (холодный вход): СНАЧАЛА таблица активных промтов в конце `docs/README.md`.** Назван промт твоей роли — он и есть твой: дальше действует ветка «С промтом», и его карта чтения ЗАКОН. Не назван («активного НЕТ») — полный маршрут ниже. ⚠ Порядок именно такой: слепой замер входа 24.08 показал, что послушная холодная сессия проходит весь маршрут (~300 тыс. знаков) и только потом узнаёт, что её работа уже заказана промтом.
1. Этот файл → `docs/README.md` (карта) → CURRENT-STATE в `docs/PROGRESS.md`. Непонятный жаргон/сокращения — `docs/glossary.md`.
2. `docs/architecture/05-decisions-log.md`: **шапка** (карта актуальности + эрраты) и **реестр** `docs/architecture/05-decisions-index.md` — одна строка на ноту. Из тел — только 23 последние. ⚠ «Живая голова» целиком в обязательное чтение НЕ входит: это 33 ноты, и требование её прочесть противоречило бы дисциплине «целиком НЕ читать» выше; остальные номера грепаются по мере вопросов. Тела закрытых эр — в слайсах `docs/archive/architecture/` (греп: живой файл → слайсы).
3. По роли (пути от КОРНЯ репозитория — прежняя редакция писала их от `docs/`, и от корня они не резолвились): Бэкенд — шапка-таблица `docs/architecture/09-target-architecture.md` (что построено) → `backend/README.md``docs/architecture/03-implementation-notes.md` (через баннер) → `docs/architecture/12-go-style-notes.md`; ⚠ порядок именно такой: сессии, впервые видящей движок, механика нужнее стиль-норм; Полигон — `eval/README.md` + `docs/experiments/00-provider-quirks.md` + `docs/experiments/09-pilot-protocol.md`; Фронт/продукт — `docs/product-requirements.md` + `docs/research/16-reader-ide-alignment.md` (через ревью-шапку) + контракт `docs/architecture/14-api-contract/`; Платформа — `platform/README.md` + зонный журнал + `docs/research/23-engine-platform-seam.md` + контракт 14; всем — шапка-таблица `docs/architecture/09-target-architecture.md` (статус слоёв). Тулчейн на чистой машине — строка «Тулчейн» в карте `docs/README.md`.