Turn the order into building admission by the disagreement the drafts already produced, with the measurement before the build and six ways it could cost us

This commit is contained in:
heaven 2026-09-12 01:12:22 +03:00
parent a703fb9446
commit 5dbb5cbe00

View file

@ -1,4 +1,4 @@
# Бэкенд-пак: ИЗ ЧЕГО СДЕЛАН БАНК — и почему его состав нельзя ни измерить, ни повторить
# Бэкенд-пак: В БАНК ПО РАЗНОБОЮ — впустить термин, который черновик уже написал двумя способами
> Выдан оркестратором №23 (сессия `textmachine-11`). Пак **$0** — платных вызовов в нём нет.
> Предмет куплен двумя платными прогонами; разбор состава банка сделан старшим коллегой по коду.
@ -43,6 +43,10 @@
## 2. Зона записи и git
- Зона — **`backend/`**, и только она.
- ⛔ **ВНИМАНИЕ, ДЕРЕВО НЕ ПУСТОЕ:** незакоммиченные файлы в `backend/` — это СДАЧА ПРЕДШЕСТВЕННИКА
(пак «купленное доставлено»), и она **в зоне твоего пака**. Это НЕ «чужая незакоммиченная работа», от
которой канон велит держаться: её сессия закончила, пак закрыт актом, лендинг мой. Сверься со мной
пингом ПЕРЕД первой правкой в `cutcall.go`, `disposition.go`, `status.go` — я скажу, заландено ли.
- **Ты не коммитишь.** Готовое дерево передаёшь мне, я лендлю. `git add -A` запрещён каноном.
- Свою секцию итогов пиши в `docs/PROGRESS.md`. Чужие незакоммиченные файлы в дереве не трогай.
- ⚠ **`/tmp` на этой машине занят на 9697 %** (tmpfs, 5.9 ГБ). Забитый tmpfs маскируется под сломанную
@ -62,72 +66,105 @@
## 4. Состав
### 4.1 ⛔ ПРОВЕНАНС УЖЕ ЕСТЬ, И Я ЕГО УЖЕ ПОСЧИТАЛ — читай это ПЕРВЫМ
### 4.1 ⛔ ЗАМЕР ВПЕРЕДИ СТРОЙКИ: во что обойдётся приём кандидата ПО РАЗНОБОЮ. **$0, и до него код не трогаешь**
Первая редакция этого промта заказывала «завести провенанс, чтобы стало что мерить». **Это было неверно:
провенанс пишется в сайдкар банк-стопа с самого начала** (`backend/internal/pipeline/mining.go`, греп
`Origin: string(c.Origin)`), и сайдкары ОБОИХ платных прогонов лежат на диске. Поймал старший коллега,
пере-снял я — **и вот числа, которые меняют предмет пака:**
**Предмет пака — впустить в банк термин, который черновик УЖЕ написал двумя способами.** Сигнал для этого
считается и лежит в дереве: `Spread` — дословно «the disagreement signal: how many DISTINCT renderings the
drafts produced» (`backend/internal/terminology/terminology.go`, греп `func (c Candidate) Spread`). Рядом
живёт `Conventions` — тот же счёт ПОСЛЕ свёртки форм, различающихся только регистром/ё/пробелами.
⛔ **И в отборе кандидата не участвует НИ ОДИН из них: ноль упоминаний в `miner_emit.go` и
`miner_detect.go`.** Мы вычисляем нужный признак, показываем его человеку и не пускаем в решение.
| канал | прогон A | прогон B | Жаккар A↔B |
|---|---|---|---|
| `both` — предложено И майнером, И банкнотой | **4** | **4** | **1.00** |
| `banknote` — только стохастическим черновиком | **65** | **62** | **0.63** |
| `mined` — только детерминированным майнером | **0** | **0** | — |
⛔⛔ **НО СКОЛЬКО КАНДИДАТОВ ОН ВПУСТИТ — НЕИЗВЕСТНО, И ЭТО ГЛАВНЫЙ РИСК ПАКА.** Я посчитал по сайдкару
стопа прогона B: из 66 термов `spread ≥ 2` у **восьми (12 %)**, и `conventions` дал ровно то же
распределение (58/4/3/1) — то есть на этой книге свёртка форм не изменила ничего. ⚠ **Но это счёт по
ПРОШЕДШИМ кандидатам, а рост кардинальности зависит от ОТВЕРГНУТЫХ**, и их мы не сохраняем. **Число,
которое решает вопрос владельца, в уликах отсутствует.**
⭐ **ЧИТАЙ ЭТО ТАК, И ЭТО ГЛАВНЫЙ РЕЗУЛЬТАТ ДВУХ ПЛАТНЫХ ПРОГОНОВ:**
1. **Детерминизм не сломан — его 6 %.** Пересечение двух каналов воспроизводится ИДЕАЛЬНО: те же четыре
поверхности, оба раза. Весь недетерминизм живёт в банкнотном канале.
2. ⛔ **Детерминированный майнер не даёт НИ ОДНОЙ уникальной поверхности.** Ноль строк `mined` в обоих
прогонах значит: всё, что он предложил, черновик предложил и так. **Его уникальный вклад пуст.**
3. ⇒ **94 % банка книги — стохастический выход модели.**
**ПЕРВАЯ РАБОТА ПАКА — получить это число, и только потом решать.** Делай РОВНО так:
**ЧТО ТЫ ДЕЛАЕШЬ ВМЕСТО «ЗАВЕСТИ ПРОВЕНАНС»:**
1. **Сухой прогон сигнала по ЧЕРНОВИКАМ обоих платных прогонов** — материал заланден:
`/home/ubuntu-26/tm-coldrun-a/stand/books/bk_ROEHZBD46ALFI43E/project.db` (glossary 69) и
`/home/ubuntu-26/tm-coldrun-b/stand/books/bk_NH6275ZIRFFTLZHG/project.db` (glossary 66).
**НЕ бери `books/gu-zhenren/door-to-file-b/bankstop/project.db`** — там `glossary` пуст (0 строк), и
твой замер даст ноль, неотличимый от успеха. **Рядом с каждым нулём печатай контрольную величину.**
2. **Напечатай таблицу приёма при порогах** `spread ≥ 2`, `≥ 3`, и то же по `conventions` — **со
знаменателем: сколько поверхностей рассмотрено всего**. Отдельной строкой — сколько из впущенных НЕ
прошли бы нынешний тип-фильтр (то есть сколько из них обычные существительные, ради которых всё
затевается).
3. **Назови, что случится с `род`/`клан`** (`家族`, 9 вхождений; `族`, 29) — попадут ли они, и при каком
пороге.
**(а) ⛔ ОТВЕЧАЕШЬ, ПОЧЕМУ УНИКАЛЬНЫЙ ВКЛАД МАЙНЕРА ПУСТ.** Майнер ранжирует тысячи кандидатов, а в стоп
доходят четыре — и все четыре дублируют банкноту. Это либо (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 ПРАВИЛО ПРИЁМА — **алгоритм проектируешь ТЫ, и вот всё, что я знаю о ловушках**
### 4.2 ⛔ ДИАГНОЗ: ГДЕ ВЫПАЛ `族` — **и механизм контраста НЕ ТОТ, что я написал в первой редакции**
**Решаешь сама и аргументируешь:** на каком признаке принимать (`Spread`, `Conventions`, их сочетание с
частотой), какой порог, и КАК это встраивается — новым признаком в `emissionEligible` или отдельной
дверью рядом.
`族` встречается в срезе **29 раз**, `家族`**9**, и ни один не попал в банк ни в одном прогоне.
⛔ **ТИП-ФИЛЬТР — вот где сегодня стоит стена, и её надо назвать явно.**
`backend/internal/miner/miner_emit.go`, функция `emissionEligible`: **первым** условием
`if !hasAnyType(c.Types, "name", "place", "title") { return false }`, **вторым**
`c.Freq < emitMinFreq || subsumed[c.Src] || runeLen(c.Src) < 2`. ⇒ `族` отсечён **безусловно как
одноруний**, а `家族`**типом** (2 руны, freq 9 при пороге 5, то есть проходит всё остальное).
**Детерминированный канал по построению эмитирует только имена, места и титулы.** Обычные термины в
банк попадают — в прогоне B их **30 из 66**, — но ИСКЛЮЧИТЕЛЬНО через банкноту, то есть через то, что
черновик сам решил назвать.
⛔ **МОЯ ПЕРВАЯ ФОРМУЛИРОВКА БЫЛА НЕВЕРНА, и, приняв её, ты «подтвердишь» гипотезу грепом и ошибёшься.**
Я написал: «словарь-контраст СОДЕРЖИТ `族` ⇒ отсечён». Контраст в майнере — **не список присутствия, а
ОТНОШЕНИЕ**: над-представленность в книге против общего китайского (`backend/internal/miner`, греп
`wordRel`, `charIndepRel`, `charOverRep`). Присутствие в словаре не отсекает ничего; отсекает **низкий
ratio при `FreqFloor`**.
⛔⛔ **ШЕСТЬ СПОСОБОВ, КОТОРЫМИ ЭТА СТРОЙКА МОЖЕТ ОБЕРНУТЬСЯ ПРОТИВ НАС. Владелец спросил о них прямо;
каждый обязан получить ответ в отчёте — замером, а не мнением.**
**Три гипотезы, различай их ЗАМЕРОМ:**
- **(i) ОТНОШЕНИЕ.** Напечатай `wordRel`/`charOverRep` и РАНГ для `族` и `家族` — это и есть прибор.
- **(ii) ПОТОЛОК ЭМИССИИ** — ряд **223**: 2110 ранжированных → 442 годных → **117 в окне потолка 200**,
то есть **325 годных поверхностей невидимы постоянно**.
- **(iii) КОНСОЛИДАЦИЯ ТЕРМИНОЛОГА** — LLM-пасс мог схлопнуть терм в составной ключ или отбросить.
1. ⛔ **САМОЕ ЕДКОЕ: приём ПО ЧЕРНОВИКУ делает банк БОЛЬШЕ зависимым от стохастики, а не меньше.**
Мы чиним недетерминизм банка — а признак приёма берём из выхода модели при `temperature > 0`. Два
прогона одной книги дадут разный `Spread` ⇒ разный приём ⇒ разный банк. **Скажи, насколько:** посчитай
приём по обоим прогонам и дай пересечение. Если оно низкое — правило усиливает ровно ту болезнь,
которую лечит, и это надо знать ДО стройки.
2. **Морфология съест порог.** Русский склоняет: «род / рода / роду» — одна передача в трёх формах.
`Spread` считает СЫРЫЕ формы, `Conventions` — свёрнутые, и разница между ними и есть цена стеммера.
На прогоне B они совпали, но стеммер снимает ровно ОДНО окончание, и на другой книге совпадут вряд ли.
3. **Кардинальность стоит МЕСТА В ПРОМПТЕ.** Банк инъектируется редактору; больше строк — либо дороже
каждый вызов, либо вытеснение других строк, и вытеснение **молчит**. Найди, есть ли кап инъекции, и
что происходит при переполнении: усечение без предупреждения — это тихая потеря именно тех терминов,
ради консистентности которых банк существует.
4. **Каждый впущенный кандидат требует `dst`**а его даёт LLM-пасс терминолога. Больше кандидатов =
больше платных вызовов на стадии, где на прогоне B **97.6 % выхода ушло в думанье, а 2 вызова из 6
провалились**. Назови, во сколько вызовов обойдётся приём при твоём пороге.
5. **Человек подписывает банк ЦЕЛИКОМ** (`D39.144`, слово владельца: «один ОК всему банку»). Чем больше
строк, тем больше непросмотренного покрывает один ОК. Это не техническая цена, а продуктовая, и её
надо НАЗВАТЬ, а не решить.
6. **Обратная связь.** Банк инъектируется в черновик следующих глав ⇒ меняет их `Spread` ⇒ меняет приём.
Правило влияет на собственный вход. Скажи, видишь ли ты здесь расходящуюся петлю.
**ЛЕЧЕНИЕ НЕ СТРОИШЬ, и довод сильнее «второго предмета».** Ранг и окно живут в замороженном
откалиброванном конфиге майнера (`backend/internal/miner`, греп `FrozenConfig`, `miner-v1`), и его сдвиг
двигает майнинг-дельту → `memory_version` → снапшот редакторской волны КАЖДОЙ резюмируемой книги. Это
версионируемая правка с пере-оплатой, а не однострочник.
**Но если диагноз окажется (ii), принеси ПРЕДЛОЖЕНИЕ с проекцией в том же паке:** сколько поверхностей
и каких войдёт при окне X, что это сделает с `族`, какова цена снапшота. Это пишется из данных диагноза,
второго захода не стоит.
**И попутно проверь то, чего не знает никто:** версионирован ли САМ майнер — входит ли его версия в
снапшот. Если нет, это ещё одна дыра детерминизма, и она твоя находка, а не мой заказ.
**Строить правило БЕЗ ответов на 1 и 3 нельзя** — это два места, где стройка «оборачивается против
нас» буквально. Остальные четыре назови и оцени.
### 4.2а ПРОВЕНАНС СТРОКИ — **доноси СУЩЕСТВУЮЩЕЕ, не проектируй новое**
Провенанс кандидата в дереве **есть**: `terminology.Origin` = `mined | banknote | both | alias`
(`backend/internal/terminology/terminology.go`, греп `OriginMined`), он печатается в таблицу стопа и
уходит в батч терминолога. **Теряется он на персистентной строке банка.** ⇒ доноси ЭТОТ словарь, второй
не заводи.
⭐ **И вот что он уже дал, посчитанный мною по сайдкарам обоих прогонов — это первое число пака, а не
следствие:** канал `both`**4 и 4 поверхности, Жаккар 1.00**; канал `banknote` — 65 и 62 при Жаккаре
**0.63**; строк «только майнер» — **0 и 0**. ⇒ детерминированная часть воспроизводится идеально, а
уникальный вклад майнера пуст.
⛔⛔ **ЗАПРЕТ, НАРУШЕНИЕ КОТОРОГО СТОИТ ПЕРЕ-ОПЛАТЫ КНИГ.** `Source == "mined"` — денежный дискриминатор
в **21 не-тестовом месте**; на нём стоит `excludeMined`, отделяющий БАЗОВЫЙ банк от обогащённого
(`backend/internal/membank/memory.go`), а базовый сворачивается в снапшот ЧЕРНОВОЙ волны. Новое ЗНАЧЕНИЕ
в `source` пройдёт мимо фильтра → майненые строки протекут в базовый банк → `baseMemoryVersion`
сдвинется → **черновая волна пере-оплатится по всей книге**. ⇒ провенанс едет **ОТДЕЛЬНЫМ полем**;
`source` не трогается; ⛔ **и новое поле НЕ добавляется в фолд `ComputeVersionScopedIn`** — он двигает
`memory_version` каждой книге.
**Пины обязательны:** значения `source` не изменились · `excludeMined` исключает ровно то же множество ·
`baseMemoryVersion` после правки НЕ сдвинулся.
⚠ И шов, о котором надо знать: строка попадает в БД не напрямую, а через YAML подписной карты →
подпись человека → `ParseEngineBankSeed`, где `source` штампуется заново. **Провенанс обязан пережить
круг через документ, который правит рука.** Плюс комментарий схемы (`backend/internal/store/migrate.go`,
греп `provenance:`) обещает значения `seed|ruby|auto`, а пишется `mined` — почини вместе с предметом.
### 4.3 `waves.workers` — **делай РОВНО так**
@ -214,9 +251,12 @@ ratio при `FreqFloor`**.
## 8. Заявление = команда
Каждое число и каждая категорика — **с командой, которой получены**. Дифф `^func Test` — исполнением.
**Три нормы кодового пака:** сверь КАЖДЫЙ клейм с результатом инструмента ЭТОЙ сессии · последний
**Четыре нормы кодового пака:** сверь КАЖДЫЙ клейм с результатом инструмента ЭТОЙ сессии · последний
абзац отчёта оказался планом — сделай его СЕЙЧАС · в длинной сессии интервальная самоверификация
субагентом против ЯВНЫХ критериев (`D39.121`).
субагентом против ЯВНЫХ критериев (`D39.121`, тело в `docs/archive/architecture/05-decisions-D39-106-123.md`) ·
**пин на УСЛОВНОЕ сообщение обязан иметь фикстуру, где оно ОБЯЗАНО прозвучать** — тест, утверждающий
только молчание, вакуумен ровно там, где сообщение ложно. Этот пак заказывает условные печати в трёх
местах (счёт по источникам, таблица приёма, операторские строки) — каждая обязана иметь такую фикстуру.
## 9. Эхо-протокол старта
@ -257,7 +297,9 @@ ratio при `FreqFloor`**.
## 13. Критерий завершённости
У каждого пункта — исход (сделано · не делаю с доводом · пинг) · круги СОШЛИСЬ · **таблица мутаций
У каждого пункта — исход (сделано · не делаю с доводом · пинг) · **круги СОШЛИСЬ: последний не дал НОВЫХ
находок, а прежние закрыты ТАБЛИЦЕЙ «находка → что сделано → ЧЕМ ПРЕДЪЯВЛЕНО»** (без таблицы «круги
сошлись» остаётся самоотчётом) · **таблица мутаций
полная, выжившие названы, КАЖДАЯ новая запись помечена `battery`** · числа сняты ПОСЛЕ последней правки ·
`df -h /tmp` рядом с итогом гейта · всё живое в ДЕРЕВЕ, а не в письме · явное **«работа завершена,
править не планирую»**. Без последнего пак считается идущим.