textmachine/docs/BACKEND_BANK_RETRY_LADDER_SESSION_PROMPT.md

132 lines
24 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. Какая проблема и что решит твой результат
Книга переводится дёшево, но **термины** — имена героев, гор, сект, техник — решает отдельная дорогая роль: терминолог предлагает передачу, классификатор ставит тип. Тип не косметика: он **форсирует способ передачи**, и ошибка в нём означает, что название места транслитерировано вместо перевода — и так **в каждом вхождении по всей книге**. Это прямой удар по цели №1: издательское художественное качество и связные термины на всю книгу.
**Замер прогона B:** на попытке 1 классификатор ответил по 4 строкам из 22 и по 0 из 24 — **42 терма из 66 остались без машинного типа**, оба батча оплачены (≈$0.0126 и ≈$0.0121), регенерации не было. У черновой стадии та же беда лечится и вылечена.
⛔⛔ **И вот предупреждение, без которого ты объявишь «дефекта нет».** Число 42 из 66 снято на ПОПЫТКЕ 1 и **в артефактах невидимо**: у неотвеченного кандидата остаётся ЭВРИСТИЧЕСКИЙ тип, поэтому в проекции банка все 66 строк выглядят типизированными, а сводка консолидации показывает «полно, выброшено 0, без ответа 0». Носитель числа — `docs/experiments/25-door-to-file-b.md` (попытка 1), а не проекция. ⇒ **мерить эффект пака по проекции нельзя**; мерило — журнал запросов прогона (`asked`/`answered` по батчам). Побочно это вскрывает дефект наблюдаемости, которого пак НЕ заказывает: человек на подписи не отличает машинный тип от эвристического.
**Главное, ради чего пак заказан.** Движок **уже вычисляет вердикт** о негодности такого ответа: попытка классифицирует выход банк-роли — именно так в журнале запросов появились пометки «упёрся в потолок» и «пустой». Но код, зовущий банк-роль, читает из попытки **только текст** и вердикт роняет на пол. ⇒ **это не новый механизм, а подключение существующего вердикта к существующей лестнице.**
**Ряды трекера, которые пак закрывает:** **451** (умный участок в точке банка — слово владельца, `D39.254` п.2), **438** (банк-роли мимо обеих ветвей лечения; там же готовая формулировка денежной мины с адресами), **435** (эскалация выключена данными), **478** (ординал батча в ключе покупки). ⚠ Ряд 451 записан как «дизайн-пак, затем стройка» — **оркестратор сознательно берёт строительную часть сразу**, потому что разбор уже сделан консилиумом и этим промтом; если по ходу увидишь, что без отдельного дизайна не выходит, это законный пинг.
## 2. Зона записи и git
**Твоя зона — `backend/`** плюс секция «Бэкенд» в `docs/PROGRESS.md`. Больше в `docs/` ничего не трогай. **Ты не коммитишь** — готовишь дерево и передаёшь оркестратору. Git-дисциплина целиком — `CLAUDE.md` §«Git-координация мультисессий», он в карте чтения ниже.
## 3. Карта чтения — ЗАКОН, пять позиций
1. `CLAUDE.md` в корне — канон проекта целиком.
2. `backend/internal/pipeline/stagerun.go`**цикл попытки: счётчики, ветви «меньше думать» и «больше потолок», эхо-регенерация.** Читать целиком, включая комментарии: там объявлено различение, на котором стоит §4.1.
3. `backend/internal/pipeline/terminologist.go` — банк-роли: сборка батча, вызов попытки, что делается с ответом.
4. `backend/internal/config/internal_call.go` — почему у внутренних вызовов хоп эскалации нулевой. Комментарий несущий.
5. `docs/architecture/18-bank-ontology.md` — что такое банк и чьё слово в нём живёт.
**Числа и адреса этого промта сняты оркестратором и советчиками; те, на которых ты строишь решение, пере-снимай сама** — заимствованное число улики не заменяет.
## 4. Что построить
### 4.1. Вынести лестницу попытки в общий контур — НАПРАВЛЕНИЕ задано, форма твоя
**Чего делать НЕЛЬЗЯ: звать `runStage` из терминолога.** Это единица «одна стадия одного ЧАНКА до терминальной диспозиции»: работа по главе, пин снапшота, рендер из шаблона, резюм через статус чанка, запись статуса в конце. У банк-батча нет ни чанка, ни статуса чанка, ни шаблона. Проложить это флагами — заплатка, запрещённая словом владельца.
**Чистый разрез:** цикл попытки — отдельная функция с двумя вызывающими. `runStage` = резюм + лестница + эскалация + диспозиция; банк-роль = лестница + разбор ответа. Второй копии цикла не появляется.
⛔⛔ **ЕДИНСТВЕННОЕ, ЧТО ЗДЕСЬ ЗАДАНО ЖЁСТКО, И ЭТО ДЕНЬГИ: ступень ключуется ЧИСЛОМ УДВОЕНИЙ, а НЕ номером попытки.** В дереве потолок — функция числа удвоений бюджета, а номер попытки считает КЛЮЧИ, и файл из позиции 2 карты чтения объявляет это различение несущим: «escalations counts BUDGET DOUBLINGS; attempt counts KEYS. They come apart on TWO paths». Номер попытки вдобавок не растёт линейно — попытка перешагивает сожжённые ключи. ⇒ **отображение «номер попытки → потолок» есть смена ключа покупки и пере-оплата уже купленных чекпойнтов.** Перечислитель ступеней делай один на всех, но параметром берёт число удвоений.
**Что ещё обязано стать параметром:**
- **допуск ступени** — «можно ли купить следующую»: у стадии книжный потолок, у банк-роли её собственный ролевой суб-бюджет;
- **судья ступени** — у стадии вердикт даёт классификатор выхода, у банк-роли он приходит **после разбора таблицы** (ответ на чужом языке, доля отвеченных ниже порога). Без этого хоп на другую модель по «упёрся в потолок» бессмыслен: другая модель потолка не лечит.
**И честно про регресс-сеть, потому что первая редакция этого промта врала.** Пинов, фиксирующих ЗНАЧЕНИЕ хеша запроса, у нас **нет**: существующие проверяют только, что хеш МЕНЯЕТСЯ при смене поля, а сквозной пин детерминизма банк-проход не гоняет вовсе. ⇒ **зелёный гейт НЕ докажет, что ты не сдвинула ключ покупки.** Первым делом построй то, что покраснеет от сдвига: голден значения хеша банк-батча. Полезный существующий якорь — тест шва, который пишет чекпойнт под хешем, выведенным продакшн-путём: он ловит расхождение пробы с попыткой, но не сдвиг обеих разом.
### 4.2. Ступень мимо бюджета — ДЕЛАЙ РОВНО ТАК
Проба «этот вызов уже оплачен» спрашивает только про **нулевую** попытку. Как только лестница начнёт покупать ступень номер один, эта ступень уйдёт мимо пробы и мимо ролевого суб-бюджета. Допуск и проба обязаны говорить об одних и тех же ступенях — это условие, а не совет.
### 4.3. Эскалация банк-ролей — РЕШИ САМА, прочитав, что защищает нулевой хоп
Банк-роли не доходят до эскалации **намеренно**. Прежде чем менять, прочти комментарий в `internal_call.go` и назови в отчёте, **что именно** он защищает: причин там несколько, и как минимум одна про чужие деньги — общий пул эскалации принадлежит черновой стадии.
⇒ Фоллбек банк-роли на другую модель обязан: не тратить чужой пул, считаться против ролевого суб-бюджета, оцениваться по цене **той модели, на которую идёт**. Ключ конфигурации — аддитивный, по образцу стадий. ⚠ Возьми у образца не форму, а **гарантию**: посмотри, чем соседний механизм себя стережёт, и перенеси это тоже.
### 4.4. ~~Тождество банк-батча~~ — ⛔ **ПУНКТ СНЯТ 17.09 ОТКАЗОМ СЕССИИ, и отказ принят.**
Посылка ряда 478 пере-мерена на настоящем батчере и НЕ подтвердилась: снятие одного решённого кандидата даёт ноль сдвигов из 246, при боевом размере батча — ноль и на 66, и на 300 кандидатах, при положительном контроле 18 из 19. ⇒ **ключ покупки не трогать.** Класс остаётся латентным и оживает лишь при мелком размере батча. Ниже — исходная формулировка заказа, оставлена как история:
>
Ключ покупки включает порядковый номер куска, а банк-батчи нумеруются по порядку ⇒ стоит фильтру снять одну решённую строку, номера всех последующих сдвигаются, и они покупаются заново при неизменном тексте (ряд **478**).
**Почему в одном паке с лестницей:** любая правка ключа один раз пере-покупает уже оплаченные банк-чекпойнты; два пака — две пере-чеканки и дважды переписанные пины.
**Развилка, и цена у неё разная.** Номер куска сегодня — целое число, оно же колонка в хранилище, ось лога и носитель инварианта «два батча не столкнутся на одном чекпойнте». Свернуть отпечаток состава в это целое — коллизии и потеря смысла колонки; завести отдельную ось в запросе — смена ФОРМАТА ключа, а она пере-чеканит **не только банк, но все стадии**. Обещание «пере-покупает один раз» верно только для первой ветви. Выбери ветвь, назови цену обеих числом и предъяви, что пере-чеканка произойдёт однажды, а не на каждом прогоне.
### 4.5. Счёт ответов — вторая половина той же дыры
Доля ответов **считается** и пишется построчным предупреждением по каждому батчу; чего нет — так это её в итоговой строке и в проекции, а итоговая строка печатает число батчей, выброшенных **бюджетом**, что читается как «сколько термов без ответа». ⚠ Не заводи третий счётчик рядом: подними существующий до итога и разведи два смысла честно.
### 4.6. Стандарт работы — слово владельца 17.09, ратифицировано `D39.258` п.3
Писать **«согласно нашим проектным высоким стандартам по решению проблемы художественного перевода»**: чистый код, рефакторинг там, где он нужен, никаких заплаток поверх неработающих решений, техдолг не копить. ⚠ Это **проверяемый** пункт, а не лозунг: отчёт называет, **что было отрефакторено и почему** (см. §13).
**Чего НЕ делать:** ансамбль моделей, кросс-модельные веса и селекцию из вариантов — закрыто ратификацией и замером, в этом паке не пере-открывается · платформу и контракт не трогать · эхо-эскалацию черновика не чинить (она выключена данными по причине ряда **435**, и это отдельный предмет).
## 5. Самопроверка ИСПОЛНЕНИЕМ
Гейт зоны (`make battery`) обязателен и самопроверкой **не является**. Сверх него — адверсариальный проход по своей готовой работе; **субагентов поднимать разрешаю явно**. Глубину выбираешь сама, направление даю я — четыре места, где этот пак мягок:
1. **Сдвиг ключа покупки** (§4.1) — у тебя нет пина, который это ловит, пока ты его не построишь. Проверь посадкой, а не цветом гейта.
2. **Ложная регенерация на банке.** Прозовые правила вердикта гасит **предикат роли** (не флаг конфигурации), и он гасит именно эхо-проверку и экран целевого языка, а классификатор потолка и пустоты работает всегда. ⚠ Не снимай предикат мутацией — это правка ПРАВИЛА, и она пометит здоровые таблицы дефектными, то есть покраснеет про другой предмет. Утверди ПОСЫЛКУ: здоровая таблица терминов не должна вызывать регенерацию, иначе это ложная регенерация за деньги.
3. **Ступень мимо суб-бюджета** (§4.2) — фикстура, где ступень номер один обязана быть отвергнута бюджетом роли.
4. **Пере-чеканка ключа** (§4.4) — доказать исполнением, что она происходит один раз.
**Мутации:** записей каталога, трогающих два твоих главных файла, — 39 из 478, и 35 из них уже в гейте (в гейте всего 267 из 478). ⇒ полный прогон каталога после рефактора обязателен и по времени оценим. Новые посадки вводи в гейт, иначе «поймана» — разовый прогон смены, а не рубеж проекта.
## 6. Оси ревью
Две-три, можешь заменить с аргументом: **денежная** (ни один путь не покупает дважды и мимо бюджета) · **качество перевода** (стало ли термов с машинным типом больше — мерило журнал запросов, не проекция) · **рефакторинг без регресса** (что переехало и чем доказано, что поведение прежнего вызывающего не изменилось).
## 7. Записка-план
До первой правки кода — короткая записка в свою секцию журнала: какой разрез выбрала, какие параметры вынесла, что решила по эскалации и по развилке §4.4.
## 8. Эхо-протокол старта
**Первым действием** — десять строк **своими словами**: скоуп, инварианты, чего не делаешь. Дословный пересказ промта подтверждает канал, но не понимание.
## 9. Что не удалось — и где прибор слеп
Секция «не удалось / не проверено» обязательна. ⚠ И вторая половина: **«где мой прибор слеп и я это знаю»** — что невидимо, почему не чинила, чем закрывается. Норма зоны: **в коде названо, в отчёте нет — значит для следующей смены не названо.**
## 10. Канал вопросов, право отказа, советчик
Конфликт промта с кодом — **пинг**, не интерпретация; право сказать «этого делать не надо» с аргументом у тебя есть. Прямой канал — механизм в `CLAUDE.md` §«Связь между сессиями»: впиши свой блок первым делом, эхо отправь по адресу оркестратора оттуда же. Тебе разрешён **один** старший советчик (`model: "fable"` явно) для развилки, которую не закрывает своё суждение; досылай вопросы ему, а не поднимай новых — его контекст и есть ценность. Он советчик, не источник истины.
## 11. Критерий завершённости — проверяемый
- у **каждого** пункта заказа исход: сделано · не делаю с доводом · пинг;
- круги **сошлись**: последний не дал новых находок, прежние закрыты таблицей «находка → что сделано → **чем предъявлено**»;
- таблица мутаций полная, выжившие названы поимённо, полный прогон каталога пройден;
- **список «что отрефакторено и почему»** — либо явное «рефакторинга не потребовалось» с доводом (§4.6);
- числа сняты **после последней правки**, у каждого команда повторения; всё живое — **в дереве**;
- гейт зоны зелёный **целиком** (сверка списком целей, а не отсутствием слова FAIL);
- сказано явно: **«работа завершена, править не планирую»**.
## АДДЕНДУМ ВЛАДЕЛЬЦА 17.09 (передан сессии релеем; ратифицирован `D39.258` п.9)
1. **Тщательно проектируй решение** — замысел раньше кода, и он предъявляется запиской-планом.
2. **Комментарии только нужные, без странных гарантий.** Не пиши гарантию, которой не стережёт ни один пин; комментарий, несущий ВЫВОД, обязан назвать условие, при котором вывод перестаёт держаться.
3. **Прозы в коде нет.** Комментарий объясняет ПОЧЕМУ, а не пересказывает, что делает строка.
4. **Решение общее для книг и языков.** Go-логика не ветвится по паре или книге: пара-специфика — в данных и языковых пакетах, книжные каноны — в сиде и брифе. Ревью-вопрос по умолчанию: «заработает ли пара, которой в репозитории ещё НЕТ, без правки Go?»
5. **Советчиков разрешено ДО ДВУХ** (прежняя норма — один), с ПОСТОЯННЫМ контекстом; вопросы досылаются тем же агентам. Советоваться предписано на ПРОЕКТИРОВАНИИ и на ПРИЁМКЕ, а не только при затруднении.
6. **Грепать `docs/`, `research/`, `experiments/` можно в любое время** — карта чтения промта это МИНИМУМ, а не потолок.
⇒ приём аддендума эхо-подтверждается, и в отчёте он идёт ОТДЕЛЬНЫМ пунктом.
---
⭐ Мы не «чиним ретраи». Мы делаем так, чтобы книга не получила героев с неверно переданными именами из-за того, что движок знал о негодном ответе и промолчал.