From da89177600ff68b1096ea13935990ba0881ad87d Mon Sep 17 00:00:00 2001 From: heaven Date: Sat, 12 Sep 2026 00:45:18 +0300 Subject: [PATCH] Take the order about what the bank is made of into the tree: the deterministic miner adds no surface of its own, and the provenance that shows it is already written beside the run --- ...WHAT_THE_BANK_IS_MADE_OF_SESSION_PROMPT.md | 263 ++++++++++++++++++ 1 file changed, 263 insertions(+) create mode 100644 docs/BACKEND_WHAT_THE_BANK_IS_MADE_OF_SESSION_PROMPT.md diff --git a/docs/BACKEND_WHAT_THE_BANK_IS_MADE_OF_SESSION_PROMPT.md b/docs/BACKEND_WHAT_THE_BANK_IS_MADE_OF_SESSION_PROMPT.md new file mode 100644 index 00000000..e9b15b0f --- /dev/null +++ b/docs/BACKEND_WHAT_THE_BANK_IS_MADE_OF_SESSION_PROMPT.md @@ -0,0 +1,263 @@ +# Бэкенд-пак: ИЗ ЧЕГО СДЕЛАН БАНК — и почему его состав нельзя ни измерить, ни повторить + +> Выдан оркестратором №23 (сессия `textmachine-11`). Пак **$0** — платных вызовов в нём нет. +> Предмет куплен двумя платными прогонами; разбор состава банка сделан старшим коллегой по коду. + +## 1. Какая проблема и что решит твой результат + +Приоритет №1 владельца — **консистентный перевод длинной книги**. Его несёт банк памяти. И вот что мы +узнали о банке двумя прогонами одной и той же книги: + +⛔ **Состав банка НЕ ПОВТОРЯЕТСЯ.** Побайтно один исходник, тождественный покупающий конфиг (sha +`pipeline-c1.yaml` совпал), одни и те же шесть чанков — предложений банка **A 98 · B 93 · общих 74, +Жаккар 0.63**. Расходится и состав, и ГРАНУЛЯРНОСТЬ ключа: один прогон предлагает `丙等资质` · +`族长家老` · `舅父舅母`, другой — их составляющие. `舅父舅母` встречается в срезе **14 раз**, есть в +банке A и отсутствует в B. + +⛔ **А ГДЕ ИМЕННО он не повторяется — теперь ИЗМЕРЕНО, и это главный результат двух платных прогонов:** +пересечение детерминированного и стохастического каналов (`both`) даёт **4 поверхности, Жаккар 1.00 — +идеально воспроизводимо**; банкнотный канал даёт 65 и 62 при Жаккаре **0.63**; а строк, предложенных +ТОЛЬКО детерминированным майнером, **НОЛЬ в обоих прогонах**. ⇒ **детерминизм не сломан — его 6 %, а +уникальный вклад майнера пуст.** ⚠ На СТРОКЕ банка этот провенанс теряется (все 69 и 66 несут +`source = "mined"`), и живёт он только в сайдкаре стопа. + +⭐ **А собирается банк из ТРЁХ источников, и два из них стохастические** (прочитано старшим коллегой по +коду, никем прежде): детерминированный WHICH-майнинг по исходнику против контраста · **банкноты, +собранные ЧЕРНОВЫМИ волнами** (выход модели при `temperature > 0`) · **LLM-пасс терминолога** +(консолидация, классификация, род) — и именно он делает гранулярность. + +**Твой результат решает вот что: сегодня нельзя ответить на вопрос «какая доля банка воспроизводима», и +поэтому нельзя ни починить недетерминизм, ни осознанно его принять.** + +⛔ **И сразу — чего этот пак НЕ делает, чтобы ты не построила лишнего:** +- **НЕ запирает состав банка в снапшот.** Воспроизводимость там, где она нужна, УЖЕ построена: + `memory_version` входит в снапшот редакторской волны, резюм того же прогона банк не двигает. А + популяцию ПРЕДЛОЖЕНИЙ свежего прогона подписывает человек — ратифицировано владельцем (`D39.144`: + «черновик и черновой банк появляются вместе → один ОК всему банку»). **Запереть предложение = отменить + майнинг.** +- **НЕ строит второй путь кандидата в банк.** Он напрашивается — центральный терм книги `族` + (**29 вхождений**) не попал в банк НИ В ОДНОМ прогоне, и «род ↔ клан» есть крупнейшая находка вычитки. + Но ПОЧЕМУ он выпал — **не установлено**, и у гипотезы есть конкурент с носителем (см. §4.2). +- **НЕ трогает деньги и усилие моделей.** Это отдельный предмет, и он упирается в платный замер. + +## 2. Зона записи и git + +- Зона — **`backend/`**, и только она. +- **Ты не коммитишь.** Готовое дерево передаёшь мне, я лендлю. `git add -A` запрещён каноном. +- Свою секцию итогов пиши в `docs/PROGRESS.md`. Чужие незакоммиченные файлы в дереве не трогай. +- ⚠ **`/tmp` на этой машине занят на 96–97 %** (tmpfs, 5.9 ГБ). Забитый tmpfs маскируется под сломанную + сборку. Уводи `TMPDIR`/`GOTMPDIR` на диск и печатай `df -h /tmp` рядом с итогом любого прогона. + +## 3. Карта чтения — ЗАКОН, дальше только по её ссылкам + +1. `CLAUDE.md` — целиком. +2. **Тела `D39.144`** (подпись банка целиком — слово владельца) и **`D39.252`** (акт прогона B) в + `docs/architecture/05-decisions-log.md`, плюс **эррата 12.09-а** в шапке того же файла. +3. **Ряды 439 и 440** в `docs/BACKLOG.md` — там оба замера с числами и границами. +4. `backend/internal/pipeline/mining.go` — сборка банка: греп `MineBankStats`, `buildBankCandidates`, + `runTerminologist`, `Source:`. +5. **Ряд 223** в `docs/BACKLOG.md` (потолок эмиссии майнера) — он несёт конкурирующую гипотезу §4.2. + +Код-факты добывай сама; `file:line` — отправные точки. **Код первичен.** + +## 4. Состав + +### 4.1 ⛔ ПРОВЕНАНС УЖЕ ЕСТЬ, И Я ЕГО УЖЕ ПОСЧИТАЛ — читай это ПЕРВЫМ + +Первая редакция этого промта заказывала «завести провенанс, чтобы стало что мерить». **Это было неверно: +провенанс пишется в сайдкар банк-стопа с самого начала** (`backend/internal/pipeline/mining.go`, греп +`Origin: string(c.Origin)`), и сайдкары ОБОИХ платных прогонов лежат на диске. Поймал старший коллега, +пере-снял я — **и вот числа, которые меняют предмет пака:** + +| канал | прогон A | прогон B | Жаккар A↔B | +|---|---|---|---| +| `both` — предложено И майнером, И банкнотой | **4** | **4** | **1.00** | +| `banknote` — только стохастическим черновиком | **65** | **62** | **0.63** | +| `mined` — только детерминированным майнером | **0** | **0** | — | + +⭐ **ЧИТАЙ ЭТО ТАК, И ЭТО ГЛАВНЫЙ РЕЗУЛЬТАТ ДВУХ ПЛАТНЫХ ПРОГОНОВ:** +1. **Детерминизм не сломан — его 6 %.** Пересечение двух каналов воспроизводится ИДЕАЛЬНО: те же четыре + поверхности, оба раза. Весь недетерминизм живёт в банкнотном канале. +2. ⛔ **Детерминированный майнер не даёт НИ ОДНОЙ уникальной поверхности.** Ноль строк `mined` в обоих + прогонах значит: всё, что он предложил, черновик предложил и так. **Его уникальный вклад пуст.** +3. ⇒ **94 % банка книги — стохастический выход модели.** + +**ЧТО ТЫ ДЕЛАЕШЬ ВМЕСТО «ЗАВЕСТИ ПРОВЕНАНС»:** + +**(а) ⛔ ОТВЕЧАЕШЬ, ПОЧЕМУ УНИКАЛЬНЫЙ ВКЛАД МАЙНЕРА ПУСТ.** Майнер ранжирует тысячи кандидатов, а в стоп +доходят четыре — и все четыре дублируют банкноту. Это либо (i) он предлагает мало, либо (ii) предлагает +много, но всё совпадает с банкнотой, либо (iii) его предложения отсекаются ПОСЛЕ ранжирования. **Напечатай +со знаменателем на каждой ступени:** сколько кандидатов ранжировано · сколько прошло контраст · сколько +вошло в окно эмиссии · сколько дошло до стопа · сколько из дошедших уникальны против банкноты. Материал +есть: обе базы и оба сайдкара (`books/gu-zhenren/door-to-file-b/` и `~/tm-coldrun-a/evidence/bankstop-paid/`). + +**(б) ПЕРЕНОСИШЬ провенанс на СТРОКУ банка, но ⛔ НЕ ЧЕРЕЗ `Source`.** Словарь изобретать не надо — он +есть: `mined | banknote | both | alias` (`backend/internal/pipeline/terminology.go`, греп `Origin`). +⛔⛔ **И вот запрет, нарушение которого стоит ПЕРЕ-ОПЛАТЫ КНИГ:** `Source == "mined"` — денежный +дискриминатор в **21 не-тестовом месте**; на нём стоит `excludeMined`, который делит БАЗОВЫЙ и +ОБОГАЩЁННЫЙ банк (`backend/internal/membank/memory.go`, греп `excludeMined`), а базовый банк сворачивается +в черновой снапшот. **Новое ЗНАЧЕНИЕ в `Source` пройдёт мимо фильтра → попадёт в базовый банк → сдвинет +снапшот всех резюмируемых книг → пере-оплата.** ⇒ провенанс едет **НОВЫМ полем**, а `Source` не трогается +вовсе. **Пин обязателен:** значения `Source` не изменились И `excludeMined` исключает ровно то же +множество, что до пака. +⚠ Новое поле = миграция (схема уже на v18 — значит v19) и минор конверта банка; платформа сайдкар +разбирает аллоулистом и новое поле игнорирует — **назови это в отчёте, не молчи**. + +### 4.2 ⛔ ДИАГНОЗ: ГДЕ ВЫПАЛ `族` — **и механизм контраста НЕ ТОТ, что я написал в первой редакции** + +`族` встречается в срезе **29 раз**, `家族` — **9**, и ни один не попал в банк ни в одном прогоне. + +⛔ **МОЯ ПЕРВАЯ ФОРМУЛИРОВКА БЫЛА НЕВЕРНА, и, приняв её, ты «подтвердишь» гипотезу грепом и ошибёшься.** +Я написал: «словарь-контраст СОДЕРЖИТ `族` ⇒ отсечён». Контраст в майнере — **не список присутствия, а +ОТНОШЕНИЕ**: над-представленность в книге против общего китайского (`backend/internal/miner`, греп +`wordRel`, `charIndepRel`, `charOverRep`). Присутствие в словаре не отсекает ничего; отсекает **низкий +ratio при `FreqFloor`**. + +**Три гипотезы, различай их ЗАМЕРОМ:** +- **(i) ОТНОШЕНИЕ.** Напечатай `wordRel`/`charOverRep` и РАНГ для `族` и `家族` — это и есть прибор. +- **(ii) ПОТОЛОК ЭМИССИИ** — ряд **223**: 2110 ранжированных → 442 годных → **117 в окне потолка 200**, + то есть **325 годных поверхностей невидимы постоянно**. +- **(iii) КОНСОЛИДАЦИЯ ТЕРМИНОЛОГА** — LLM-пасс мог схлопнуть терм в составной ключ или отбросить. + +⛔ **ЛЕЧЕНИЕ НЕ СТРОИШЬ, и довод сильнее «второго предмета».** Ранг и окно живут в замороженном +откалиброванном конфиге майнера (`backend/internal/miner`, греп `FrozenConfig`, `miner-v1`), и его сдвиг +двигает майнинг-дельту → `memory_version` → снапшот редакторской волны КАЖДОЙ резюмируемой книги. Это +версионируемая правка с пере-оплатой, а не однострочник. +⭐ **Но если диагноз окажется (ii), принеси ПРЕДЛОЖЕНИЕ с проекцией в том же паке:** сколько поверхностей +и каких войдёт при окне X, что это сделает с `族`, какова цена снапшота. Это пишется из данных диагноза, +второго захода не стоит. +⚠ **И попутно проверь то, чего не знает никто:** версионирован ли САМ майнер — входит ли его версия в +снапшот. Если нет, это ещё одна дыра детерминизма, и она твоя находка, а не мой заказ. + +### 4.3 `waves.workers` — **делай РОВНО так** + +Прогон B шёл **строго последовательно**: сумма латентностей 18.5 мин при стенных 19.3, перекрытий ноль. +Причина — `Waves.Workers` **по умолчанию 1** (`backend/internal/config/pipeline.go`, греп +`Wave workers default to 1`), и в боевом конфиге ключ **не задан вовсе**. Комментарий у дефолта называет +это «wave-structured but sequential, deterministic run» — **но ратификации у этого нет**, а исполнитель +СТРОИЛСЯ под N: `waverun.go` (греп `result ORDER is deterministic`) прямо говорит, что порядок +результата детерминирован по индексу элемента **независимо от порядка завершения**. + +**Что делаешь:** выставляешь `waves.workers` в боевых конфигах — **но число берёшь НЕ с потолка.** +⛔ `max_concurrency` задан у **ОДНОЙ модели из десяти** (`models.yaml`, греп `MaxConcurrency`; ноль = +без ограничений), и для deepseek его НЕТ. **Кап берётся из вендорской доки** — норма квирков «идём в +официальную доку, не гадаем», — а не назначается. Пин над боевыми конфигами: **`workers ≤ max_concurrency` +модели стадии**; нет капа у модели — нет и числа воркеров больше единицы, и это пинится. + +⛔ **И ПИНИШЬ БАЙТ-ИДЕНТИЧНОСТЬ — но у неё ПЯТЬ способов выродиться, а не один.** Я назвал только первый; +остальные четыре дал старший коллега, и каждый делает пин пустым: +1. **Один элемент волне** — единица параллелится сама с собой. +2. **Порядок завершения не разошёлся** — четыре воркера над МГНОВЕННЫМ фейком заканчивают в порядке + старта. Фикстура обязана ЗАСТАВИТЬ порядок разойтись (фейк с латентностью, обратной индексу) и + **напечатать фактический порядок завершения**. +3. ⛔ **Не тот артефакт.** `request_log`, `events_outbox.seq`, `updated_at` расходятся ЗАКОННО при + конкуренции. Пин обязан НАЗВАТЬ множество сравниваемого: чекпойнты по `request_hash` · `chunk_status` + (диспозиция и финальный хеш) · экспорт побайтно · свёртка банка · `retrieval_state` · снапшот-ид — с + нормализацией сортировкой, по прецеденту `backend/internal/pipeline/golden_test.go` (греп там же). + ⚠ И «снапшот идентичен» — тривиально: он считается из конфига ДО волны. Несущее — чекпойнты и финалы. +4. **Одна волна вместо двух** — единицы редактора многочанковые, и разойтись может именно там. +5. ⛔ **Пин не мутирован.** Посади зависимость от порядка (общий счётчик в колбэке либо свёртку банкнот по + порядку завершения) и покажи, что пин краснеет **ТЕКСТОМ про предмет**. Иначе он утверждает молчание. + +⚠ **Гонки под `workers > 1` у нас проверяются** — 14 тестов задают больше одного воркера, 11 из них +четыре, пакет под `-race` чист (пере-снято мною 12.09). Но **ни один живой прогон с N > 1 не шёл**, и +это надо сказать в отчёте прямо. + +### 4.4 ДЕНЕЖНАЯ ПОСЫЛКА, КОТОРАЯ ПЕРЕСТАЛА БЫТЬ ВЕРНОЙ — **делай РОВНО так** + +`backend/configs/models.yaml`, блок `deepseek-v4-pro`: комментарий утверждает, что **«перебор бюджета +БЕСПЛАТЕН — резервация транзитна, списание идёт по фактическому usage»**. ⛔ **Это ложно с `D39.230`:** +оборванный вызов книжится **ПО ОЦЕНКЕ** (`backend/internal/pipeline/cutcall.go`, греп +`settleUSDForCutCall`), а оценка **пропорциональна `max_tokens`**. На этой посылке стоит решение «флор с +запасом, а не впритык» — и стоит теперь неверно. + +**Что делаешь:** исправляешь текст посылки и **называешь в отчёте**, меняет ли это само решение о флоре +(пере-решать флор в этом паке НЕ надо — назови цену и отдай мне). + +### 4.5 ПРОТУХШИЕ УТВЕРЖДЕНИЯ В КОДЕ — **реши сама, какие брать, и объяви** + +Найдены старшим коллегой при разборе. **Твоя зона — только движковые:** +`config/pipeline.go` (греп `sequential, deterministic`) — против `waverun.go`; `reservegate.go` (греп +`THREE values`) — при четырёх константах, если ещё не чинено; `cutcall.go` (греп `the run was stopped`) +— на обрыве от падения соседа. +⚠ **Платформенные НЕ ТРОГАЙ** (`pgstore/credits.go`, `runner/runner.go`, `pgstore/runs.go`, +`ingest/events.go`) — их отнесу я. Назови в отчёте, какие движковые взяла и какие оставила с доводом. + +## 5. Где этот пак мягкий — четыре места, назвал я, веер выбираешь ты + +Мандат самопроверки — **исполнением**; субагенты разрешены явно. Адверсариальный проход по СВОЕЙ готовой +работе обязателен. + +1. ⛔ **Провенанс, схлопывающий множественный источник в один ярлык, ХУЖЕ его отсутствия** — он выглядит + измерением. Кандидат, предложенный и майнером, и банкнотой, обязан быть отличим от однобокого. +2. ⛔ **Диагноз `族` легко получить НЕ ТОТ.** «Ноль после контраста» и «не смотрел контраст» выглядят + одинаково: у каждой ступени печатается ЗНАМЕНАТЕЛЬ. И спроси себя, на ЧЬИХ данных считаешь — банк A и + банк B разные, и ступень, где терм выпал, может отличаться между прогонами. +3. ⛔ **Пин байт-идентичности при 1 и 4 воркерах вырожден, если фикстура даёт ОДИН элемент волне.** + Одна единица параллелится сама с собой. Фикстура обязана дать волне столько элементов, чтобы порядок + завершения МОГ разойтись, и доказать это печатью. +4. ⛔ **Правка комментария — не правка механизма.** Если исправленная посылка §4.4 меняет чьё-то + решение, скажи ЧЬЁ; если не меняет — скажи, почему, и чем это предъявлено. + +⚠ И общее, стоившее трёх смен подряд: **зелёная батарея плюс полный мутационный каталог сходимостью НЕ +являются.** Направленный второй читатель находил 6, 7, 9 и 13 дефектов при полной зелени. + +## 6. Предметные оси ревью + +Выбери 1–3 и назови какие. Мой приор: **провенанс под множественным источником** · **знаменатель на +каждой ступени диагноза** · **детерминизм под конкуренцией**. + +## 7. Записка-план ДО работы + +Перед первой правкой — записка в `docs/PROGRESS.md`: что меняешь, чем предъявишь, где ждёшь сопротивления. + +## 8. Заявление = команда + +Каждое число и каждая категорика — **с командой, которой получены**. Дифф `^func Test` — исполнением. +⛔ **Три нормы кодового пака:** сверь КАЖДЫЙ клейм с результатом инструмента ЭТОЙ сессии · последний +абзац отчёта оказался планом — сделай его СЕЙЧАС · в длинной сессии интервальная самоверификация +субагентом против ЯВНЫХ критериев (`D39.121`). + +## 9. Эхо-протокол старта + +**Порядок двух первых действий:** сперва свой блок в `/tmp/textmachine-channel`, потом эхо. +**Эхо** — ≤10 строк СВОИМИ словами: что поняла · что считаешь опасным · что считаешь неверным. Не +пересказ: дословный пересказ подтверждает канал, но не понимание, и ошибку промта повторяет вместе с ним. +**Адрес бери из файла канала** (блок `role=оркестратор`), сверившись с `ListAgents`. + +## 10. Что НЕ удалось — обязательная секция отчёта + +И вторая половина: **«где прибор слеп и я это знаю»** — что невидимо · почему не чинила · чем +закрывается. ⭐ Норма: **«в коде названо, в отчёте нет — значит для следующей смены НЕ названо».** +⚠ На прошлом паке прямой вопрос дал ПЯТЬ находок сверх отчёта, включая улику, существовавшую в одной +копии. Отвечай на него до того, как я спрошу. + +## 11. Канал вопросов и право отказаться + +Конфликт промта с кодом — **пинг мне, не интерпретация**. Право сказать «этого делать не надо» с +аргументом у тебя есть, и им пользовались: в двух паках подряд сессия была права, а не я. +⛔ **Тесты и гейты под зелень не подгонять.** Правка, вызванная ЗАКАЗАННОЙ сменой поведения, — +обслуживание, и протухший тест держать не нужно; но она **ОБЪЯВЛЯЕТСЯ**: что изменилось, какой тест это +описывал, куда уехала гарантия. +⛔ **И слово владельца 12.09, которое сильнее всякой осторожности:** «нам не нужно держать неправильно +работающую функциональность из-за техдолга, тестов каких-то старых». Замерила, что починка дорога, — +это ПЛАН, а не довод держать дефект. + +## 12. Прямой канал + +Механизм — `CLAUDE.md` §«Связь между сессиями». Впиши свой блок ПЕРВЫМ действием. Нужной роли нет ⇒ +канала нет, и это нормальный случай: НЕ опрашивай сессии подряд. + +### ⭐ Старший коллега — Fable 5. **Разрешён ОДИН на сессию (слово владельца)** + +Поднимаешь **одного** агента на модели **`fable`** и держишь весь пак. Вопросы ДОСЫЛАЕШЬ ему, второго не +поднимаешь: ценность в накопленном контексте. Модель задавай ЯВНО. Он **советчик, а не источник истины** — +его посылки проверяются деревом. ⭐ Для калибровки: в этом паке ровно он прочитал, как собирается банк +(чего не сделал никто), и снял два моих пункта из пяти как лечение симптома. + +## 13. Критерий завершённости + +У каждого пункта — исход (сделано · не делаю с доводом · пинг) · круги СОШЛИСЬ · **таблица мутаций +полная, выжившие названы, КАЖДАЯ новая запись помечена `battery`** · числа сняты ПОСЛЕ последней правки · +`df -h /tmp` рядом с итогом гейта · всё живое в ДЕРЕВЕ, а не в письме · явное **«работа завершена, +править не планирую»**. Без последнего пак считается идущим.