# Промт сессии: БЭКЕНД — вайр-батч «род, экран цели, заголовки инъекций» > **Роль:** бэкенд. **Зона записи:** `backend/` и своя секция «Бэкенд» в `docs/PROGRESS.md` — это > единственное разрешённое каноном исключение из «`docs/` — зона оркестратора». Чужие зоны > (`platform/`, `frontend/`, `eval/`) читаешь, не правишь. **Не коммитишь** и не трогаешь индекс и > историю — полный список запретов и причина: `CLAUDE.md`, «Git-координация мультисессий». > Норматив стиля — `docs/architecture/12-go-style-notes.md`. ## Какая проблема и что изменит твой результат Движок обещает род персонажей на проводе — директива ратифицирована `D39.21`, механизм доставки построен и работает. **Данных ему не даёт никто:** промпт терминолога возвращает ровно три поля (термин · перевод · уверенность), поля рода в ответе нет, а майнер берёт `gender` только из ручного сида. Значит на любой книге, которую никто не сидировал руками, ось рода мертва **по построению**, и «плывущий род» в тексте — не дефект рендера, а отсутствие входа. Рядом лежат ещё три правки того же провода, каждая ратифицирована и ни одна не построена. После пака: род производится авто-путём · полный связный перевод на чужой язык перестаёт проходить как здоровый · редактор получает единый закон-блок вместо двухсекционки · банковый контур включён в боевой конфиг · жанр ушёл из промптов. И всё это одним пере-захватом голдена, а не пятью. ## Карта чтения — пять позиций, дальше только по их ссылкам 1. `backend/README.md` — устройство движка · `docs/architecture/12-go-style-notes.md` — норматив. 2. `docs/PROGRESS.md`: CURRENT-STATE и строки бэклога **210 · 46 · 113 · 134 · 140 · 184 · 197 · 198 · 204** (греп по номеру в таблице). 3. **Состав и его доводы — здесь, в этом файле.** Разбор «почему пункты собраны вместе и что намеренно НЕ берётся» лежит в отработавшем плане `docs/archive/reports/NEXT_PACKS_PLAN_2026-09-03.md` §1 — ⚠ это АРХИВ: читать как ДОВОД, инструкции оттуда не исполняются, приказ несёт этот промт. Ратифицированные решения по очереди — нота **D39.190** (грепом по номеру). 4. Журнал решений, номера грепом (`grep -n '^## D39.NNN'`): **D39.21** (род должен доезжать) · **D39.93** (форма экрана цели) · **D39.104** (банк на проводе — закон) · **D39.105/D39.108** (доктрина заголовков и павший гейт) · **D39.147** п.2в (140 — стройка, не развилка) · **D39.138** п.2в (жанр выкидываем) · **D39.64** П0 (безусловный фолд `EmbeddedVersion`). 5. `docs/architecture/15-money-path.md` — денежный путь; читать §2 про суб-бюджеты банк-ролей. ⚠ Ратифицированное вложено в тело этого промта; **код-факты добываешь САМ** — указатели ниже отправные точки, код первичен. Числа даны с командой получения: пере-ранишь — сойдётся; не сошлось — это находка, неси пингом, а не подгоняй работу под текст. ## Состав — шесть пунктов, в этом порядке ### 1. Строка 210 — РОД НЕ ПРОИЗВОДИТСЯ ВОВСЕ (цель №1 бэклога) Механизм доставки построен: `backend/internal/membank/memory.go` (греп `genderConstraintNote`) кладёт род в черновую инъекцию. Входа нет: ``` grep -n -i gender backend/prompts/zh-ru/terminologist.md # ноль полей рода grep -n 'meta.gender' backend/internal/miner/miner_emit.go # род только из сида ``` **Делай РОВНО так:** род начинает производиться авто-путём, и это доказывается СКВОЗНЫМ прогоном «терминолог произвёл → отрендерилось в инъекции», а не юнит-тестом на конструкцию. **Решаешь сам и аргументируешь — развилка НЕ выбрана за тебя:** поле рода в ответе терминолога · отдельный проход · признать сид-только и закрыть строку отказом. Выбор объявляешь с ценой (байты батча терминолога двигают его `RequestHash`). ⛔ **ВТОРОЙ ЗАМОК, без которого первый пункт не даёт НИЧЕГО.** Род рендерится только у строк со статусом `Confirmed`, а произведённое терминологом приезжает auto-строкой. Снятие замка следует из доктрины `D39.104` (банк на проводе — закон для всех строк независимо от статуса), **но оно обязано быть СКАЗАНО и вынесено пингом на ратификацию оркестратору, а не выведено тобой молча.** Пока замок не снят, поле у терминолога ничего не меняет на проводе — так и напиши в отчёте, если решишь не снимать. ⚠ Вес: следующий платный замер полигона (15 глав с характер-листами) без этого пункта **ложно-отрицателен по построению** — «полей пола в банке нет вовсе». ### 2. Строка 113 → потом 46 — экран целевого языка. ПОРЯДОК ОБЯЗАТЕЛЕН **Сначала 113, и это не формальность.** Числа, на которых стоит вся строка 46 («18 из 20 · 0 ложных на 1055 · запас 13×»), получены ВРЕМЕННЫМ тестом, который сессия удалила; воспроизвести их сегодня нечем. **Делай РОВНО так:** корпус-фикстура в репо (~20 off-target + ~40 здоровых, с движковой предобработкой) плюс регресс-тест на реальный запас. ⛔ **СТОП и пинг**, если фикстура не воспроизводит 18/20 при нуле ложных или запас меньше 3×: тогда предпосылка строки 46 пала, и стройка по ней — трата. Затем сам экран. Дизайн ЗАМОРОЖЕН и ратифицирован: closed-set причин (`D39.92` п.1) и изолированный модуль с именованными причинами (`D39.93`). ⚠ **Три вещи, которых нет в спеке, и они меняют работу:** - `EFFORT_HANDLE §5.4` шаг 6 велит переиспользовать `FlagCJKArtifact` — **это СНЯТО `D39.93` п.2** (именованный флаг + явный вход в `escalatable()`). Нота бьёт спеку. - Вторая половина дыры — `detectLatinInsertion` без `TargetScriptNonLatin()` (`backend/internal/checks/sanitizer.go`); реестр §Б-46 велит «чинить тем же диффом». - Новый именованный флаг — **16-я причина**, а карта платформы рукописная на 15 (`grep -c '":' platform/internal/ingest/notes.go` → 15) ⇒ платформа отдаст `unspecified` с ERROR. Носитель — строка **204** / ряд `PD-246`. **Пинг платформе обязателен** (в отчёт, чужую зону не правишь). **Решаешь сам и аргументируешь:** состав и форма корпус-фикстуры 113 · имя и текст новой причины флага · где именно стоит вход в `escalatable()`. ### 3. Строка 134 — инжект-заголовки под доктрину D39.105 Гейт ПАЛ (`D39.108`): текст = отправленная строка пробы 18 **БЕЗ** оговорки области (оговорка опровергнута §A.4 — НЕ вносить). **Делай РОВНО так — ТЕКСТ заголовка не меняется вовсе.** Меняется рендер: секция `editor_unverified_header` не рендерится (двухсекционка → один блок) · маркер ⟨проверить⟩ не рендерится · то же у заголовка транслятора. Статусы строк и подписная таблица **не трогаются** (`D39.104` п.1). ⛔ **МИНА, и выбор твой, но объявленный.** Правка `backend/internal/lang/data/injection.txt` двигает `EmbeddedVersion` БЕЗУСЛОВНЫМ фолдом (`D39.64` П0) и `cutTag` манифеста ⇒ пере-чеканку ВСЕХ `unit.id` ⇒ платформа при смене `manifest_key` СНОСИТ `unit_resolutions` книги (`platform/internal/pgstore/readmodel.go`, греп `recut :=` и `delete from unit_resolutions`) — это строка **198**, и её гейт «до первого реального пользователя». Рычаг у тебя есть: **снять рендер в Go, данные не трогать** — тогда двигается только `RequestHash`, мёртвые строки данных допустимы до следующего касания. **Решаешь сам и аргументируешь, но выбор ОБЪЯВЛЯЕШЬ явно** и, если тронул данные, пишешь об этом первой строкой отчёта. ### 4. Строка 140 — банковый контур в shipping-c1: СТРОЙКА, не развилка ⚠ Текст строки называет это «СТОП-решением» — он СТАРШЕ ратификации. `D39.147` п.2(в) уточнением владельца 17.08: внесение «ратифицированно живёт в wire-батче 182 — одним касанием перед первым платным прогоном; **отдельной развилки нет**». Журнал бьёт бэклог. ``` grep -n 'terminology\|banknote\|classify' backend/configs/pipeline-c1.yaml # 0 — не построено ``` **Делай РОВНО так:** банковый контур (банкнота + терминолог + классификатор) включается в c1. ⛔ **Суб-бюджеты банк-ролей калибровать ×4.47** — `15-money-path.md` §2 прямо говорит, что сегодня они «режут ОПЛАЧЕННУЮ работу по протухшей калибровке»: на холодном прогоне `classify_budget_usd` 0.02 оборвал классификатор дважды. **Решаешь сам:** конкретные числа после умножения и надо ли поднимать их сверх множителя. **Цена НАЗЫВАЕТСЯ в отчёте** (двигает промпт черновика ⇒ `RequestHash` книг на c1), но не спрашивается. ### 5. Строка 184(а) — снять `{{genre}}` из промптов пары Слово владельца 16.08, `D39.138` п.2в дословно: «Просто выкидываем». Состав числом не держим: ``` grep -rln '{{genre}}' backend/prompts/ # сегодня шесть файлов ``` **Делай РОВНО так:** снять из промптов И поле из канона брифа (двигает `BriefHash`, то есть КАЖДЫЙ `RequestHash` — потому и внесено в это окно, а не потом). Влияние жанра на качество не измерено и уже не будет. ⚠ **Свободы здесь нет намеренно:** пункт предписан целиком, решать в нём нечего. Упрёшься во что-то, чего промт не предусмотрел, — пинг, а не своё усмотрение. ### 6. ДОФИКС чужого пака + ФЧ-7 — одним пунктом ⚠ **Почему это здесь.** По канону дофикс адресуется той же сессии, что делала пак. Её больше нет (проверено `ListAgents` 04.09), поэтому остаток едет сюда. **Это чужая недоделка, а не новый заказ** — и в отчёте её надо называть отдельно от своей работы. Остаток приёмки (`D39.187` п.4): - **Развилка операторской строки прибита с ОДНОЙ стороны.** `VolumeStop.String()` развёл предложение на «книга кончилась» и «грант придержал», но две посадки в новый код переживают весь пакет: под ними в смешанном состоянии (`Carried=3, Left()=1`) печатается «reached the END of the book … Still in the book: 1 unit(s) NEVER delivered» — то же самопротиворечие в зеркальной форме. Лог-развилка при этом прибита с обеих сторон, то есть образец рядом. - **Граница `bound()` не прибита:** `Carried > 0` → `Carried > 1` переживает пакет, и прогон с ОДНИМ перенесённым юнитом на конце книги не отдаёт отчёт вовсе — тихий лимит, анти-паттерн `D39.165` §1б. - **Три числа отчёта протухли снова** — сняты до последней правки каталога. **Делай РОВНО так:** каждая из двух посадок получает тест, который от неё краснеет, И запись в `backend/cmd/tmmutate/mutations.json`. ⚠ **ФЧ-7 фикс-листа (строка 197) — паника поверх ПОЙМАННОГО потолка.** Денежный шов, не проверялся никем. **Форма — проверка ИСПОЛНЕНИЕМ, а не стройка: воспроизвести, и чинить ТОЛЬКО если воспроизводится.** Тем же касанием пере-скоупить строку 197: ФЧ-1/4/5 закрыты, ФЧ-6 по коду выглядит закрытым, **ФЧ-2/3/8 остаются НЕ ПРОВЕРЕННЫМИ и обязаны быть названы непроверенными**, а не тихо опущены. ## Границы — что НЕ делать - ⛔ **Не двигать:** схему хранилища движка · `manifestVersion` · `StreamVersion` · версию контракта. Понадобилось — **стоп и пинг**, не «сделаю аккуратно». - ⛔ **Не заводить новый embed-файл** (реестр §Б-46: это перекупка всех пар). - ⛔ **Не переиспользовать `FlagCJKArtifact`** (снято `D39.93` п.2). - ⛔ **Не менять семантику переноса слота** — владелец 03.09 отложил её словом «подумаем». - ⛔ **Не брать строки 131 · 105(а) · 14 · 119 · 124 · 115 · 160 · 161 · 142** — они жильцы того же окна или отдельных паков, и их очередь решает оркестратор, не ты. - ⛔ Не трогать чужие зоны, `.env`, соседний worktree `/home/ubuntu/projects/textmachine`. - ⚠ **Общность движка:** Go-логика не ветвится по паре и книге. Ревью-вопрос по умолчанию — «заработает ли пара, которой в репо ещё НЕТ, без правки Go?». Пара-данные — `internal/lang` и `configs/langpacks/`, книго-каноны — сид и бриф. ## Свобода и её разметка **«Делай РОВНО так» (отступление = пинг):** порядок 113 → 46 · СТОП по фикстуре, если запас < 3× · текст заголовка не меняется · статусы и подписная таблица не трогаются · нота бьёт спеку у `FlagCJKArtifact` · суб-бюджеты ×4.47 · жанр снимается и из промптов, и из канона брифа · обе посадки дофикса краснеют · ФЧ-7 — проверка, а не стройка · все запреты раздела «Границы». **«Решаешь сам и аргументируешь» — и только это:** развилка производства рода · снимать ли второй замок (со СКАЗАННЫМ пингом) · трогать ли данные в 134 (с объявлением) · конкретные числа суб-бюджетов · форма фикстуры 113 · форма тестов и записей каталога · порядок работ внутри пака. ⚠ Катч-олла «всё остальное — сам» нет: чего нет ни в одном списке — это пинг, а не твоё усмотрение. ## Мандат самопроверки — исполнением, не перечитыванием `make battery` — **предусловие, а не отчёт.** Обязательны все четыре, каждое с ПРЕДЪЯВЛЯЕМЫМ артефактом: 1. **Дифф `^func Test` исполнением, а не памятью:** `grep -rn '^func Test' backend --include=*_test.go | wc -l` до и после, плюс пофамильный дифф. **Удалённых имён должно быть 0**; не 0 — назвать каждое. 2. **Голден пере-захватывается с МАСКИРОВАННЫМ диффом:** в нём меняются только названные версионные оси и **ровно две строки диспозиций**. ⛔ Изменилась хоть одна здоровая строка — **СТОП и эскалация**, а не пере-захват. 3. **Собственные адверсариальные посадки ВНЕ шести пунктов** — механизм `cmd/tmmutate` на копии дерева (`cp -a backend /tmp/<имя>/backend`). Артефакт: красный вывод на каждую посадку и **отдельный список тех, что батарея ПЕРЕЖИЛА** — это и есть находки. 4. **Отдельный проход по СВОЕЙ ГОТОВОЙ работе свежим контекстом.** Субагенты разрешены явно; модель задавай ИМЕНЕМ и знай, сколько их у тебя работает. ⚠ **«Прошёл, находок нет» отчётом НЕ является:** ноль обосновывается тем, ЧТО искалось и какими командами. **Отчёт о движении провода обязателен:** двинулся ли `cutTag` — предъяви `tmctl manifest` до и после на стендовой книге и дифф `unit.id`. ### Предметные оси ревью — уязвимы ИМЕННО в этом паке 1. **Ложные срабатывания экрана цели на ЗДОРОВОМ русском с латинскими термами.** Положительный контроль — фикстура 113: 18/20 при нуле ложных и запас ≥3×. Без него экран не сдан. 2. **Род: все существующие тесты конструируют его руками.** Нужен сквозной контроль «терминолог произвёл → отрендерилось» И отрицательный «сид побеждает произведённое». 3. **134: маркер снят, а пост-чек жив.** Проверь, что снятие маркера не сломало обработку `Ambiguous`. 4. **140: бюджеты режут оплаченную работу.** После ×4.47 предъяви, что классификатор на стендовой книге не обрывается. ⚠ Запрет подгонки тестов и гейтов — `CLAUDE.md` (`D39.183`). Край, который тебе понадобится: **этот промт ЗАКАЗЫВАЕТ смену поведения в пунктах 1–5**, и протухший под неё тест правится как обслуживание — но правка ОБЪЯВЛЯЕТСЯ: что изменилось, какой тест это описывал, куда уехала гарантия. ## Отчёт **Записка-план ДО работы** — эхо-протокол старта, ≤10 строк «скоуп · инварианты · что НЕ делаю», в секцию «Бэкенд» `docs/PROGRESS.md`. Первым действием, до кода. **Комплектность против заказа — механически:** пройди по шести пунктам состава и по таблице разметки и отчитайся **ПО КАЖДОМУ**. Эта тема проваливалась несколько раз на том, что исполнялся первый пункт, а нумерованный остаток бросался. **«Заявление = команда»:** каждое число и каждая категорика — с командой получения, которая это число реально печатает. Приёмка пере-ранит твои команды; команда, печатающая «ok» вместо числа, считается отсутствующей. Гейты и счёты гнать **ПОСЛЕДНИМ действием**, после того как текст дописан. **Обязательная секция «Что НЕ удалось и что НЕ проверено».** Исходов ТРИ, и «не проверено» ≠ «опровергнуто» ≠ «сделано»; третий законен и ожидаем. Сюда обязательно попадают ФЧ-2/3/8 и решение по второму замку рода, если ты его не снял. **Конфликт промта с кодом или доками — ПИНГ через владельца, не интерпретация.** И у тебя есть **право сказать «этого делать не надо»** с аргументом, включая пункты состава и границы: сессия, приносящая развилку вместо тихой девиации, делает правильно. Промт писан по коду на HEAD своей смены; код первичен, и если ты видишь другое — это находка, а не твоя ошибка. ## Прямой канал Механизм целиком — `CLAUDE.md`, «Связь между сессиями»: свой блок в `/tmp/textmachine-channel`, сверка с `ListAgents` перед отправкой, канала нет — нормальный случай, сессии подряд не опрашивать. Что добавляет этот пак: **эхо-записку отправь ПЕРВЫМ действием по адресу оркестратора** — это и есть проверка канала.