37 lines
14 KiB
Markdown
37 lines
14 KiB
Markdown
# Промт бэкенд-сессии: ФИКС-ПАК БАНКА «КЛАСТЕРЫ + НАБЛЮДАЕМОСТЬ» (строка 128, + хвост 129)
|
||
|
||
**Выдан 04.08.2026, оркестратор №13, по санкции владельца 04.08 (зафиксирована D39.103 п.1; гейт строки 128 снят) и D39.102.** Ты — бэкенд-сессия. Зона записи: `backend/` (код+тесты+puml тем же коммитом-пакетом) + отчёт `docs/archive/reports/BANK_CLUSTER_FIXPACK_2026-08-XX.md` + пинг в `docs/PROGRESS.md` секция «Бэкенд». **НЕ коммитишь** — дерево готовишь, лендит оркестратор. ⚠ В дереве живёт ЧУЖОЕ: `platform/*` (модифицированный и новый, ждёт приёмки P0) — не трогать и не «прибирать». **Деньги: $0 — платных вызовов НЕТ вообще**; тесты и голден локально. Перекупка бэнк-батчей случится на следующем живом прогоне — в пак не входит, её цену только НАЗВАТЬ в отчёте.
|
||
|
||
**Первый деливерабл — эхо-блок ≤10 строк** (как понял скоуп · четыре работы + хвост · инварианты · что вне скоупа; подтверждения не жди).
|
||
|
||
## §0. Рамка
|
||
|
||
Вход пака — research/24 §G (принят D39.102; детальный дизайн-синк уровня функций — черновик `docs/archive/reports/DRAFT_BANK_ARBITRATION_V1_2026-08-04.md` §G, читать ЕГО) + находки приёмки D39.102 п.3. Замеры-основания: химера семьи на границе батча (research/24 §B4: одна модель, батч 0 слитно / батч 2 раздельно), 18/149 невидимых противоречий консолидаций на живом банке, «почему у терма такой dst» неответимо по артефактам (§A7), 8/45 голда = одна конвенция семьи.
|
||
|
||
**Инварианты (не трогать):** эмиссия auto/draft — терминолог не может ничего утвердить (`terminologist.go:31-35`); `Select`/пост-чек/эскалация; семантика Merge/AttachKWIC (кроме опц-перфа); ратифицированное «банкнота парсится только finish=stop» (`05-decisions-log.md:624,730`). **НЕ строить** (закрыто числами D39.102): равноправный совет · кросс-модельные веса · self-consistency · селекция из вариантов · отказ-сигнал · эмбеддинг-фетч. **G4 (кластерный роутинг) в пак НЕ входит** — это правило дизайна замера строки 5, кода сейчас не требует. **Ревью-вопрос общности:** «заработает ли пара, которой в репо НЕТ, без правки Go?» — семьи/асимметрия имя-реалия = ДАННЫЕ пары; пара без данных ⇒ канал инертен.
|
||
|
||
## §1. Онбординг (карта, целиком не читать; жаргон — `docs/glossary.md`)
|
||
|
||
`CLAUDE.md` (цели+гардрейлы) → CURRENT-STATE `docs/PROGRESS.md` → `research/24` §A/§B4/§G + черновик §G → D39.102 · D39.69 (три примитива банка) · D39.65 (со-батчинг чинит серию) → код: `internal/terminology/{terminology.go,series.go,classify.go}` · `internal/pipeline/{terminologist.go,mining.go,banknote.go}` · `internal/miner/miner_emit.go` · `internal/membank/memory.go` · `internal/lang/` (данные: `script-series.txt`) → `12-go-style-notes.md` §0.
|
||
|
||
## §2. Работы
|
||
|
||
**G1. `DetectFamilies` рядом с `DetectSeries`** (`terminology/series.go`). Вход тот же `[]Candidate` + параметры семей из ДАННЫХ пары (расширение `script-series.txt` новой колонкой или соседний файл — реши и обоснуй; НЕ Go-константы). Правила: имена (тип после классификатора) — общая ПРЕФИКС-морфема ≥2 рун; реалии — общая СУФФИКС-морфема ≥MinRootRunes (head-final письмо); асимметрия имя/реалия — тоже данные. Без транзитивного замыкания: якорь = сама корневая морфема; кандидат входит в ≤1 семью; специфичный длинный корень бьёт короткий, затем большая семья; **серия сильнее семьи ТОЛЬКО при несовпадающих корнях** — серия и семья, делящие одну корневую морфему (转-случай), СЛИВАЮТСЯ в один батч-юнит. Выход — тот же `map[string]int`, мёржится с seriesID перед `Batch` (со-батч готов — `terminology.go:917-960`; oversize-WARN — у вызывающего, `terminologist.go:276-281` через `BatchRunes` `:969-973`). Туда же два фикса приёмки: (а) **многорунные модификаторы серий** — 十一转 (3 руны) выпадает из 2-рунной серии 一转…九转 на ранге 11 и серия рвётся по батчам; форму реши сам: отдельное правило серия-канала (переменная длина модификатора) ЛИБО слияние с семьёй по общему корню — критерий один: линейка рангов 1..12 держится ОДНИМ батч-юнитом, существующее поведение равнодлинных серий не регрессирует; (б) **майнерские containment-пары** (元海 ⊂ 元海空窍, оба mined) — сегодня без Related и без атомарности в батчере (`terminology.go:195-198` считает только banknote-only) — в один юнит тем же механизмом.
|
||
|
||
**G2. `ConsolidationConflicts(cands, out)`** (`terminology/terminology.go`) — тонкий брат `CanonConflicts`: те же containment+`lexemeSubset` (`:787-812`), но правая сторона — консолидации ТЕКУЩЕГО прогона между собой. Вызов в `runTerminologist` после сборки `out` (рядом с `terminologist.go:335`); WARN с именованными парами + счётчик в `terminologyResult` + колонка стоп-таблицы. $0, evidence-сторона, не фолдится.
|
||
|
||
**G3. Наблюдаемость арбитража.** (а) `BankStopRow` += `Signals []string` (уже вычисляются per-VARIANT и выбрасываются — печатай сигналы ТОП-варианта, либо вплети по-вариантно в Variants-строку — реши), `Invented bool` (норм-dst ∉ вариантов черновиков), `Conf int`; (б) третье поле «уверенность 0–100» в ответе терминолога — строка в `prompts/zh-ru/terminologist.md` (дата-правка; PromptSHA двигает батчи тем же разом, что G1); ⚠ ловушка парсера: числовой хвост ` \d{1,3}` снять КАК conf ДО ре-джойна полей (`terminology.go:880-885`), иначе молча въедет в dst; **запрещённая форма зафиксирована D39.102**: conf — только сортировка листа ревью «сначала неуверенное», никаких кросс-модельных сравнений и «скор решает»; (в) `reasoning_content` в схему НЕ заводить (debug-сайдкар за флагом, вне снапшота); (г) находки приёмки: **alias-джойн подписной карты** — предложения, пришедшие через алиас кластера, не попадают в note представителя (`miner_emit.go:242`, `mining.go:354-364`; маршрут aliasOwner в Merge уже есть — `terminology.go:160-192`), карта расходится со стоп-таблицей; **имена эвиктнутых** — рядом с `NEvicted` детальный список (форму хранения выбери БЕЗ новой миграции схемы — ловушка неидемпотентных миграций v8–v14, строка 49а); **per-batch «спросили N / ответили M»** + WARN на ПУСТОЙ ответ батча (`terminologist.go:296-299` — сейчас молчаливый continue) и классификатора (`:403-404` — пустой ответ молча; WARN на непустой мусор уже есть, `:412-414`); тест `TestTerminologistEmptyReplyIsLoud` покрыть НАСТОЯЩЕЙ пустой веткой (сейчас фикстура непустая — имя теста врёт).
|
||
|
||
**G5. `foldVariants`:** счёт голосов по `NormalizeTargetForm`-фолду при показе сырых форм; рядом со spread — «конвенций» (folded spread); Via-провенанс при фолде не терять first-wins'ом (`terminology.go:228-234` — консенсус может пометиться «proposed for алиас»): агрегировать прямые+алиасные честно. Косметика (топ двигается 1/75) — делать заодно с G3.
|
||
|
||
**Хвост 129 (банкнота-парсер).** `banknote.go:236`: `dst := parts[1]` голым при 3-польном формате — «Фан␣␣Юань» банкует полу-имя, хвост уезжает в тип и падает в `"term"`. Фикс: ре-джойн середины, когда ПОСЛЕДНЕЕ поле ∈ `bankTypeOK` (`banknote.go:73-74`, закрытый словарь), иначе весь хвост в dst (2-польная строка); зеркалить дисциплину ре-джойна терминолога (`terminology.go:875-890`). Тест на «Фан␣␣Юань» в обеих формах. Цена фолда: авто-банк изменится только на реальных случаях двойного пробела — в отчёте назвать, нашёлся ли хоть один в артефактах `~/books/gu-zhenren/coldrun-a/` (замороженный эталон, ТОЛЬКО чтение).
|
||
|
||
**Опции (только если чисто ложатся, $0):** перф строки 37 — `AttachKWIC` через готовый Aho-Corasick (`membank/memory.go:872-918`); гигиена `BanknoteTruncated` — колонка недостижима в проде (`banknote.go:341` жёсткий false): либо честно провести флаг из исчерпанного length-ретрая, либо снести ветку+колонку+стейл-коммент (поведение «finish=stop-only» НЕ менять — ратифицировано); `NoDst` — узкий префикс-матч испорченного сентинела («⟦TM-NO-DST⟧.», кавычки) до `wellFormedLemma`.
|
||
|
||
## §3. Фолд-ось и голден (обязательная секция отчёта)
|
||
|
||
Состав батчей терминолога → `RequestHash` бэнк-батчей: G1+G3(промпт)+**G5** двигают их ОДНИМ разом — перекупка центовая, волны/снапшоты книг НЕ двигаются (проверь и предъяви: snapshot id волн не меняется). ⚠ G5 — НЕ только печать: фолд-счёт и Via меняют drafts-строки на wire (`terminology.go:441-449`, `:643-653`). Вне снапшота — только G2 и печать стоп-таблицы. Голден: если payload бэнк-батчей в голдене меняется — пере-захват ОДИН раз, явно названный в отчёте (не тихо); голден-счётчики волн обязаны пройти БЕЗ пере-захвата.
|
||
|
||
## §4. Самопроверка и СТОП
|
||
|
||
Гардрейлы, задеваемые работами: **`backend/.env` НЕ читать** · **PUML не рендерить в svg/png** (владелец смотрит расширением). Мандат 12.07: ревью ИСПОЛНЕНИЕМ своего кода + явный бэкенд-ревью после кода. Вся батарея (`go build ./... && go vet ./... && go test ./...`) зелёная; archguard-тесты не трогать. Отчёт: что сделано по каждой работе с `file:line` · девиации от этого промта с причинами · фолд-предъявление §3 · чего НЕ сделал и почему · **план верификации эффекта на следующем ХОЛОДНОМ прогоне** (D39.103 п.1; что и как смотреть — назвать конкретно). Пинг в PROGRESS «Бэкенд» кратко. **СТОП — приёмка оркестратора** (адверсариальная, клеймы пере-проверяются исполнением).
|