37 KiB
PACK-14 «генеральность-пасс» — приёмочный отчёт (2026-07-24)
Ревью-шапка оркестратора №7 (24.07, приёмка исполнением, два воркфлоу: 11 линз ~970k ток. + доприёмка дельты 4 линзы; 0 блокеров). Байт-точность КАЖДОГО переноса независимо сверена против git HEAD (refusal 12/12 · injection 6/6 с ведущими пробелами · dc-регексы · санитайзер · CJK-числительные · фонотактика · форманты — ноль расхождений); парити EXACT свежими
-count=1прогонами; golden байт-нетронут; тесты не ослаблены (2 удалённых ассерта — законные замены). Поправки к телу отчёта: (а) Приложение A — ведро «distinct/matches (8 refs)» = греп-артефакт: все 8 в комментариях, кодовых ссылок 0; заголовок «miner→membank 35» реально 32 полных вхождений / 14 кодовых; остальные вёдра точны, вывод «хойст первым» НЕ задет; (б) ёфикатор = 38 слов (строка «40 ru-слов» — обсчёт в прозе); (в) свип-47 воспроизводится как 41 (точный класс) + 6 строк ё/кана (класс сессии был шире заявленного регекса), скрытых пар-данных нет; класс «пунктуация-сепараторы» в 47 не представлен (перенос из классификации-100). Дельта доприёмки принята (generic-Палладий по аддендуму, c2-segmentation, README-пути, want-list magnitude, packAlgoVersion v2). Остаток в пак-15 (зафиксирован): тесты unknown-category-толерантности и required-fail Палладия · fail-loud оверлея уровнем выше (пропавший overlayRoot/чужой подкаталог/категория-опечатка в overlay-файле — тихие) · семантика override unionStringMap · isRuTarget/'ru'-швы · empty-probe гард lintMagnitudeScale · дуп терминаторов chunker/coverage ·第. Прод-оверлей 古月 подключён оркестратором в оба стендовых book.yaml (rerun2).
Бэкенд-сессия. Источник: docs/BACKEND_GENERALITY_PASS_SESSION_PROMPT.md (9 пунктов) + два аддендума
оркестратора (A: ingest 章节節回+CJK-числительные → та же ед. точки истины, что у чанкера; B: форманты
等/转/阶). Норматив: docs/architecture/12-go-style-notes.md §0. Перенос ДАННЫХ, не редизайн алгоритмов.
Сессия НЕ коммитит.
Вердикт: ✅ жёсткий инвариант выполнен
- golden БАЙТ-ИДЕНТИЧЕН —
testdata/golden/capture.goldenне тронут (git diffпуст). Сильнее допущенного «version-only»: у golden-книги нет langpack (ja→ru,langpack_rootне задан →pack==nil), поэтомуpackVersion()==""и её снапшот НЕ двигается ни от одного НОВОГО langpack-файла;TestGoldenсверяет capture побайтно и зелёный. - майнер-парити EXACT —
TM_MINER_PARITY=1:n=13618 catastrophe{方源:0 蛊:1 蛊师:2 古月:22} recall@proposed=0.9655— тождественно дореформенному (вкл. 古月-механику через книго-расширение). go build/vet/test -raceзелёные (весь модуль, вкл. новыйinternal/lang).
Ключевой факт, определивший архитектуру
golden — ja→ru книга БЕЗ langpack (pack==nil), но она живьём: (1) флагает hard_refusal (RU «Не могу
помочь»), (2) инъектит русские заголовки глоссария в wire (16×), (3) режет главы 第X章, (4) style_flags=0.
Значит рефузал-паттерны, CJK-числительные глав и →ru-инъекцию НЕЛЬЗЯ держать в книжном паке (nil для golden).
request_hash фолдит snapshotID (render.go) — любое движение снапшота golden-книги сдвинуло бы wire. →
Два дома данных (правило, выдержавшее «100 языков» линзу владельца)
configs/langpacks/<src>|<pair>/+ книжный overlay — пер-исходник / пер-пара / пер-книга данные. Добавить язык = положить каталог, без перекомпиляции; убрать = удалить каталог; загрузчик падает ГРОМКО, называя файл (никогда тихо-пусто). Сюда: item 1 (surnames/古月), 5 (терминаторы, Палладий- фонотактика), 6 (DC-таблицы), addB (форманты). Overlay: добавить/убрать КНИГУ = ±один каталог; DC-таблицы OPT-IN (убрать файл → чекеры инертны, не болтаются).internal/lang/data/(go:embed, секционировано по языку/таргету) — данные, нужные движку БЕЗ книжного пака (golden доказал: рефузал, CJK-нарезка, →ru-инъекция — все без langpack). Добавить язык = добавить секцию в один data-файл; убрать = удалить секцию. Перекомпиляция — приемлемо: это инженерные КОНСТАНТЫ (версионируются с бинарём, как код), а байт-точность no-pack golden запрещает фолдить их в книжный пак. Сюда: item 3 (refusal.txt), 4+addA (cjk-section.txt), 2 (injection.txt), sourceAbbrevs (sentence-abbrev.txt).
По пунктам (что сделано, чем доказана нейтральность)
1. 古月 ВОН из общего zh-langpack. Удалён из configs/langpacks/zh/surnames-compound.txt. Механизм —
книго-скоупный overlay: новое поле book.yaml: langpack_extend (каталог той же раскладки), lang.LoadWithOverlay
делает АДДИТИВНЫЙ union (множества дополняются, слайсы append; overlay ничего не удаляет), байты overlay
фолдятся в Version() (правка книжного канона = громкий --resnapshot ТОЛЬКО этой книги). Парити: testLangPack
грузит testdata/langpack-overlay-guzhenren → эффективный пак = старый (base ∪ {古月}) → {古月:22} EXACT. Стенд-
overlay создан /home/ubuntu/books/gu-zhenren/langpack-extend/zh/surnames-compound.txt. Прод-book.yaml —
см. «Хвосты владельцу».
2. Инъекция-тексты → таргет-данные, с гейтом. glossaryBlockHeader/editorConstraintHeader/маркер
⟨проверить⟩/3 gender-ноты вынесены в internal/lang/data/injection.txt (target-keyed, lang.InjectionTextsFor),
рендереры гейтятся на tx.HasData() — →en книга получит ПУСТО, не русский блок (это и есть фикс утечки).
Значимые ведущие пробелы ( (муж.…, ⟨проверить⟩) сохранены дословно (парсер НЕ триммит value). renderFormatVersion
НЕ тронут → снапшот golden не двигается → wire байт-идентичен (проверено golden). Langpack-ФАЙЛ (а не embedded)
отложен: golden без пака потребовал бы target-loader вне book-langpack_root, что сдвинуло бы снапшот golden —
запрещено инвариантом.
3. Рефузал-блэклист → универсальные embedded-данные. internal/lang/data/refusal.txt (секции en/ru/ja/zh
- маркер),
disposition.goстроитrefusalREизlang.RefusalPatterns(). Байт-в-байт 12 паттернов в том же порядке (сверено скриптом). golden флагаетhard_refusalтождественно.
4 + addendum-A. CJK-числительные — ОДНА точка истины. internal/lang/data/cjk-section.txt (digit/unit
значения, zero, chapter_unit) — читают И чанкер (isHeadingNumeral/cjkSectionDigit/cjkSectionUnit, путь
заголовков, nil для golden), И ingest (chapterNumeralRE строится из HeadingNumeralClass(), detectChapterUnit
итерит ChapterUnitOrdered — авторский порядок сохранён для детерминированного тай-брейка). Устранён
ingest↔chunker байт-дубль. golden режет 第X章 тождественно (ingest живёт для golden — верифицировано TestGolden).
sourceAbbrevs → internal/lang/data/sentence-abbrev.txt (секции по ИСХОДНИКУ, en=29 токенов); чанкер потребляет
секцию en (как и раньше — универсально; исходник-параметризация сплиттера = мелкий отложенный шаг, чтобы не
трогать 18 колл-сайтов SplitChunks на не-приёмочном пути).
5. Терминаторы 。!? + Палладий-фонотактика. zh/sentence-terminator.txt (p.SentenceTerminator,
splitMinerSentences); фонотактика jqx/ретрофлексы/ü-финалы → zh-ru/palladius-phonotactics.txt
(PalladiusRetroflex/VFinal/VFinalInitial), l/n-исключение стало данными vfinal_initial. Майнер-only,
парити EXACT.
6. DC-таблицы → пар-данные, регексы = алгоритм. dcCNNum+dcRuHourWord+dcRegisterNegList → OPTIONAL
zh-ru/dc-checkers.txt (lang.DCCheckerData), прокинуто через cheapGateConfig (nil пак → пусто → чекеры
0 → golden style_flags=0). ДЕТЕКТ-регексы (时辰/千万/成/терем-паттерны) остались как пар-скоупный
алгоритм чекера (§12.2 — «данные наружу, алгоритм остаётся»).
7. Калибровка (config/pipeline.go). Только пере-документирование (числа НЕ тронуты): дефолты 1797/3200/ 1.1978/0.3852 помечены как «zh-ru пар-калибровка = последний generic-fallback», шиппинг-конфиги (c1/армы) ставят блок ЯВНО (пар-конфиг = источник истины). Релокация в langpack ОТВЕРГНУТА (была бы мёртвой для всех живых путей: конфиги ставят явно, у golden нет langpack; least-mechanism §12.1). Числа держатся EXACT: no-langpack книга (golden) чанкается на этом fallback — пере-выведенное число сдвинуло бы её границы→wire.
addendum-B. Форманты 等/转/阶. zh/title-formant.txt (p.TitleFormant, formantType). Рядом с TopoSuffix
(сосед уже data-driven). Майнер-only, парити EXACT.
9. Промпты → prompts/zh-ru/. backend/prompts/{translator,editor,editor-mono,judge-selector}.md →
prompts/zh-ru/ (git mv, БАЙТЫ не тронуты — снапшот фолдит PromptSHA256 от СОДЕРЖИМОГО, не пути). Обновлены 5
шиппинг-конфигов (../prompts/zh-ru/…) + 4 тест-ссылки на реальные файлы. Тесты, грузящие реальные c1/арм-конфиги
(prompt_pack_test, echo_mine_test), зелёные.
Item 8 — свип-добор (полный grep non-test .go, построчно)
Метод: изолирован non-comment grep [\x{4e00}-\x{9fff}]|[а-яА-Я] (строчные комментарии срезаны). Было 133
дата-литерала → перенесено 33 (items 1–6+addA/B) → осталось 100, классификация:
- SQL-DDL комментарии (migrate.go, 26): русская документация ВНУТРИ raw-string схемы. Не пар-данные, 0 поведения. OK / вне скоупа (это перевод комментариев, отдельная забота).
- Диагностика/сообщения-флагов (~11):
book.go:188(Р7),models.go:184(Р4)/231,pipeline.go:411(Р2),checkers_zh_ru.go:63/119/124/200,cheapgates.go:451/294/319,checkers:285— operator-диагностика / observability-строки (англ.-первичные, цитируют матч для человека). НЕ wire, НЕ пар-данные. OK. - Пар-скоупный ДЕТЕКТ-алгоритм (регексы), §12.2 (данные уже вынесены, регекс остаётся):
checkers_zh_ru.go:34/38/101/102/103/117/118/122/175/178/187/283(DC1/DC2/percent/broken-word детект);sanitizer.go:213/215/217/219/240/251/362(ru-таргет editorial-preamble/note/invalid-sign детект). OK. - Алгоритм-инвариантные литералы (OK-generic):
chunker.go:222(класс СЕПАРАТОРОВ пунктуации :、,。…);memnorm.go:180-181(ё→е фолд ключа памяти, 1-символьное правило);memseed.go:570(ー/・ в кана-ридингах, ja-норм);miner_palladius.go:71(ъ-drop перед сегментацией).ingest.go:128— мой новый регекс,第остался литералом (кандидат — см. ниже). - Ратифицированный DEFER (НЕ тронут):
cheapgates.go:361translit-interj блоклист (ара-ара/маа/…) — D39.16 явно (ja-филлеры, мис-кей-ловушка). ✅ оставлен.
Кандидаты СЛЕДУЮЩЕГО пака (тот же класс, НЕ в подтверждённом фикс-листе — решение оркестратора)
Одного класса с перенесёнными, но не названы в 9 пунктах/аддендумах; байт-нейтральны (golden фаерит 0), но переносить их сейчас = расширять скоуп сверх санкционированного + повтор D39.16-концерна «живой пара-агностик». Флагаю для след. пака:
cheapgates.go:265-276yofikator homograph-whitelist (40 ru-слов) — ru-таргет readability-данные (класс DC6). Нужен ru-TARGET langpack-слот (сейчас нет).cheapgates.go:459-619万/億 magnitude-gate — zh-исходник числ-значения (万萬億亿兆 — ДРУГОЙ инвентарь, не section) + ru-стемы (тысяч/миллион/…). Кандидат: расширитьlang.CJKSectionкатегориейmagnitude+ ru-слот.sanitizer.goru-фрагменты — data-экстракция лексем-детекторов в ru-таргет-слот (регексы = алгоритм).ingest.go:128第— маркер главы; можно добавить вcjk-section.txtрядом с chapter_unit (1 руна).
«100 языков» линза (ответ на вопрос владельца)
- Добавить пару: положить
configs/langpacks/<src>/(11 required src-файлов)+<src>-<tgt>/(2 pair + опц. heading/dc-checkers) + book.yaml. НИ строки подinternal/pipeline. Загрузчик fail-loud называет отсутствующий файл. Смелл:title-formant/surnames-*осмысленны только для CJK-исходника (весь минер CJK-центричен — ПРЕ-существующее свойство, не ухудшено; для не-CJK исходника миннер сам подлежит переосмыслению). - Добавить таргет: секция в
injection.txt/refusal.txt— правка ДАННЫХ + перекомпиляция (go:embed). Оправдано: инженерные универсалии/таргет-генерики. - Убрать язык: удалить каталог пака / секцию embedded-файла — ничего не болтается (DC opt-in инертен; overlay опционален; загрузчик громкий). Тесты не ломаются на удалении пары (fail-loud по требованию).
Хвосты владельцу (операционка, вне зоны backend/)
- Прод-
book.yamlgu-zhenren (стендrerun2/book.yaml,book-mistral.yaml): добавитьlangpack_extend: /home/ubuntu/books/gu-zhenren/langpack-extend— иначе прод-майнинг потеряет 古月 (overlay- каталог уже создан на стенде). Не тронул сам: зона книжных данных владельца + закрытый эксперимент rerun2. Любой ре-ран и так --resnapshot (langpack Version() сдвинут новыми файлами). - Стенд pipeline-конфиги (
rerun2/pipeline-*.yaml) и docs, ссылающиеся на старый путьbackend/prompts/…(истор. записи в archive/experiments) — обновить путь наprompts/zh-ru/…при следующем касании (зона оркестратора/владельца).
Само-проверка (мандат 12.07) + адверсариальный 4-линзовый ревью
Ревью ИСПОЛНЕНИЕМ: каждый item верифицирован golden+parity сразу после кода (не в конце). Линзы: байт-точность / парити / общность-ja-ru / масштаб-100-языков (доп. линза владельца).
Итог адверсариального 4-линзового ревью (воркфлоу, 4 независимых агента, 289k токенов)
- БАЙТ-ТОЧНОСТЬ: CLEAN — не опровергнуто. Агент независимо байт-сверил КАЖДЫЙ перенесённый литерал против git HEAD: injection (6 значений вкл. ведущие пробелы: unverified_marker len=13, gender len=31), refusal (12 паттернов, joined_equal=True), cjk-section (digit/unit/zero MATCH, chapter_unit ПОРЯДОК [章 节 節 回], heading-класс symmetric-diff пуст), sentence-abbrev (en=29 exact), dc-checkers (11+9+6 rows match), Палладий- фонотактика/форманты/терминаторы MATCH, промпты = чистые rename (0 байт). golden capture пуст в git, TestGolden байт-сверка PASS.
- МАЙНЕР-ПАРИТИ: CLEAN — не опровергнуто (свежий -count=1). Overlay-union доказан аддитивным (base−古月 ∪ {古月} = старый 16-сет); l/n-исключение фонотактики логически тождественно старому switch.
- ОБЩНОСТЬ: CONCERNS — 1 MINOR + 3 NOTE (ниже, все либо пофикшены, либо документированы).
- МАСШТАБ-100-ЯЗЫКОВ: CONCERNS — 1 MAJOR (пофикшен) + 3 MINOR/NOTE (документированы).
Пофикшено по ревью (пост-ревью, верифицировано golden+parity):
- MAJOR (масштаб):
LoadWithOverlayТИХО игнорировал overlay-файл вне манифеста (опечаткаsurname-compound.txtили книжныйheading.txtв overlay → приватный канон не доезжает до майнера, recall падает БЕЗ сигнала). Фикс:overlayDirFilesсканирует overlay-каталоги и падает громко, называя неожиданный файл. + тест (misnamed-overlay fails loud). Восстанавливает fail-loud-гарантию на масштабе десятков книг-overlay. - NOTE (масштаб):
refusal.txt— комментарий-заголовки# --- xx ---вводили в заблуждение («удали секцию = отключи детект для пары»). На делеRefusalPatterns()читает плоско, ВСЕ паттерны фаерят для ВСЕХ книг. Комментарий переписан: секции ОРГАНИЗАЦИОННЫЕ; удаление триммит УНИВЕРСАЛЬНЫЙ сет (только#-строки — байты паттернов, golden не сдвинут). - MINOR (масштаб): header
srcFiles— уточнён скоуп: «drop a directory» верно ВНУТРИ zh-family name-miner морфо-схемы; другое семейство исходников требует новых Pack-полей (не просто каталог).
Документированные остатки (не фикшу — конфликт с инвариантом/мандатом/пре-существующее):
- MINOR (общность): калибровка = ТИХИЙ zh-ru дефолт при пропуске блока (ломает fail-loud). НЕ фиксится: item 7 предписал «оставить механизм», а golden (ja→ru) ПРОПУСКАЕТ блок и опирается на этот fallback — падение громко на пропуске сломало бы golden. Тайтен возможен лишь когда golden сам явно проставит сегментацию (будущий пак, который и так пере-снимет golden).
- NOTE (общность+масштаб):
sourceAbbrevsзахардкожен наen— исходник-параметризация сплиттера отложена (18 колл-сайтов SplitChunks, не-приёмочный путь). Секция не-en = мёртвые данные до тредаsourceLang. - NOTE (общность+масштаб): DC2
lintMagnitudeScaleдержит НЕЗАВИСИМЫЙ CJK-числ-парсер (万/億/兆), дублирующийlang.CJKSection— пре-существующий, self-gating (инертен на не-zh), не тронут этим диффом. Кандидат след. пака (в списке item-8). - NOTE (общность): DC ДЕТЕКТ-регексы пар-скоупны в Go (§12.2 by-design: данные вынесены, детект-алгоритм остаётся; self-gating → добавление ПАРЫ не требует Go, только СВОИ чекеры пары — да).
- NOTE (масштаб): двух-домовая когезия — шов. →ru target-wire-text в ДВУХ домах: injection (embedded, recompile) vs heading.txt «Глава {n}» (pack, data-drop). Причина — байт-точность no-pack golden: то, что golden НУЖНО без пака → embedded; пар-гейтнутое, что golden НЕ трогает → pack. Честный шов, задокументирован; унификация потребовала бы target-loader вне book-langpack_root (сдвиг снапшота golden — запрещён). + сиблинг target/source-данные ещё в Go (cheapgates ё-политика/оному/magnitude) — граница data/algorithm проведена неравномерно (кандидаты item-8).
Финальная верификация (пост-фиксы): go build/vet clean; TM_MINER_PARITY=1 go test -race ./... весь зелёный;
парити n=13618 {方源:0 蛊:1 蛊师:2 古月:22} EXACT; git status golden capture пуст (байт-идентичен).
ДОБАВКА: полный data-out чекеров/гейтов/санитайзера (директива владельца + оркестратора)
Триггер: владелец (после core-пака) — «магические названия остались в checkers_zh_ru.go/checkers_pack13_test.go; что при +100 языках? это мелкие примеры, ты всё отловил?». Честный ответ: НЕТ — core-пак вынес LOOKUP-таблицы, но оставил DETECTION-регексы + сиблинг-гейты как «алгоритм/DEFER» (слишком мягко для планки 100 языков). Решение оркестратора: доводи data-out, структуру НЕ трогай (сплит — след. пак с форм-фиксами). Выбор владельца: «Full: все паттерны → данные, Go generic» + «тесты грузят фикстуры из пака».
Внешняя сверка (харнесы /home/ubuntu/projects/tmp, 5-агентный воркфлоу)
- crush (Charm, Go AI-агент, ~300 .go) — ~71 фокус-пакет, один каталог = один концерн; провайдеры = ДАННЫЕ (внешний SDK + JSON-каталог, 0 per-provider Go); промпты = embedded
.md; пост-обработка РАЗНЕСЕНА по фокус-пакетам, НЕ «checkers-куча». Сильное свидетельство против нашей 38-файловой кучи И за «volatile-ось = данные». - anthropic/openai-go — плоский root = кодоген-артефакт (не образец); но ручные части = МАЛЫЕ single-purpose пакеты (
apijson/apiquery/…). - GalTransl/AiNiee (домен, что мы зеркалим) — валидируют data-мандат (глоссарий TSV, промпты per-язык, WHICH-чеки = config-список, control-codes
regex.json= ДАННЫЕ). НО обе ТЕКУТ языком в ТЕЛА чекеров (残留日文/独白男他 gated on target_lang; per-lang Unicode-регексы) — ровно наша утечка; AiNieeregex.json= чистый контр-пример = наш фикс.
Что вынесено (Full data-out)
checkers_zh_ru.go → checkers.go, ПОЛНОСТЬЮ пар-агностичен. DC1/DC2/percent DETECTION-паттерны (shichen_re/ru_hours_re/qianwan_*/shushiwan_*/cheng_re/decimal_fraction_re/percent_word) → пар-пак dc-checkers.txt (pattern<TAB>key<TAB>value, verbatim); компилируются ОДИН раз в compileCheckers → *dcCheckers спек, живёт в r.checkers (openRunner) → cheapGateConfig. Target-general (broken-word -йть) → embedded internal/lang/data/target-ru.txt. dc*-символы стали ключами данных; чекеры — методы generic-спека, nil-инертны для no-pack.
cheapgates.go: yofikator homograph-whitelist (38 слов) → target-ru yo_homograph; 万億 magnitude — CJK-парсер (digit/unit/magnitude 万萬億亿兆) ДЕДУП в lang.CJKSection (закрыл reviewer-NOTE о дубле), ru-стемы (тысяч/миллион/…) → target-ru magnitude_stem. lintYofikation/lintNumberMagnitude — методы спека. Оставлено (документировано): ё↔е фолд (1-символьная орфография = алгоритм), dialogue-dash (пунктуация), translit-interj ара-ара/… = РАТИФИЦИРОВАННЫЙ DEFER (D39.16, prompt NOT-do — единственный ru-output-блоклист, придержан).
sanitizer.go: 4 preamble + trailing-note + edit-meta + invalid-sign регексы → target-ru (извлечены из исходника СКРИПТОМ, round-trip byte-match — не перепечатка). Санитайзер уже isRuTarget-гейтнут → паттерны = ru-target данные, загружаются ruSanitizer = lang.TargetChecksFor("ru"); strip/detect-АЛГОРИТМ остаётся. «ru»-ключ зеркалит гейт (тред таргета = follow-up, как sourceAbbrevs).
Тесты грузят из пака: testCheckers(t) = compileCheckers(pack.DCCheckers, TargetChecksFor("ru")); checkers/cheapgates-фикстуры прогоняют АЛГОРИТМ над паттернами пака — 0 дублирования пар-значений (входные примеры-сценарии остаются, §0.3 легитимно).
Дома по ГЕЙТИНГУ: source-gated пара-чекеры (DC1/DC2/percent, нужен zh-исходник) → пар-пак (nil для golden→инертны); target-general (register/broken/yofikator/magnitude-стемы/sanitizer, бегут на любом →ru) → embedded target-ru (нужны no-pack golden'у); source-CJK (magnitude-руны) → embedded cjk-section.
Байт-точность (пост-каждый-инкремент): golden БАЙТ-ИДЕНТИЧЕН (capture.golden не тронут — вкл. ch6, где санитайзер СРЕЗАЕТ ru-преамбулу → доказано, что паттерны из данных = те же байты); парити EXACT n=13618 {方源:0 蛊:1 蛊师:2 古月:22}; -race весь зелёный. Свип: 100→47 остаток (26 SQL-коммент migrate.go · flag-МESSAGE-диагностики checkers/cheapgates · 1-символьные фолды ё→е/ъ/kana · пунктуация-сепараторы · translit-DEFER · 第-маркер ingest — кандидат). Все классифицированы/легитимны.
Приложение A — карта связности подсистем (измерено grep'ом, вкл. тесты) — ДЛЯ ПРОМТА СЛЕД. ПАКА
Кандидаты-пакеты и их файлы: miner (miner*.go, mining.go — 8) · membank (memory/memnorm/mempostcheck/memseed/seeding — 5) · chunk (chunker/ingest — 2) · checks (cheapgates/checkers/sanitizer/coverage/quality/regressionguard — 6). Драйвер (runner/bookrun/waverun/wave/stagerun/chunkrun/resume) + инфра (snapshot/render/export/status/banknote/disposition/escalation) = композит-корень.
Кто ссылается ВНУТРЬ каждого (non-test · TEST):
- miner ← non-test: runner:2, waverun:2, seeding:2 (узко!) · test: miner_test:63, miner_parity:7, seedlint:4, waverun:2.
- membank ← non-test: waverun:18, wave:14, runner:13, snapshot:13, +многие (горячий путь) · test: memory:78, memseed:54, memnorm:38.
- chunk ← non-test: waverun:12, wave:8, runner:5, status:5, stagerun:5, memseed:4 · test: chunker:35, ingest_encoding:28, ingest:23.
- checks ← non-test: chunkrun:17, waverun:16, status:16, export:9, disposition:9 · test: sanitizer:90, coverage:29, regressionguard:19, cheapgates:15.
Латеральная связность — НЕ «ноль» (уточнение к survey «star topology»): есть ОБЩИЙ СУБСТРАТ, который надо ХОЙСТНУТЬ ПЕРВЫМ, иначе сплит потечёт:
- miner → membank: 35 refs, но это ШАРЕД-утилиты, не membank-API:
normalizeSourceKey@memnorm (12 — текст-нормализация, общая для майнера И банка),loadGlossarySeed/seedTerm/seedAlias/seedFile@memseed (9 — майнер читает СИД как GT/entity-guard),runesEqual@mempostcheck (3),distinct/matches@memory (8 — мелкие дженерик-хелперы). - membank → chunk: 7 (
Chunk-тип), checks → membank: 19 (memoryEntry/pickedEntry/tokenizeCyrillic), chunk/miner → checks: 6+6.
Вывод для сплита (порядок): (1) ХОЙСТ шаред-базы ПЕРЕД подсистемами — Chunk/MinerChunk value-типы + текст-нормализация (normalizeSourceKey/runesEqual/tokenizeCyrillic) + сид-типы (SeedTerm/loadGlossarySeed) в базовый пакет (напр. internal/pipeline/model + internal/text); (2) затем miner (самый узкий: 6 внешних не-тест ссылок, импортит только lang+store+base) → checks (чистые ф-ии над строками, импортят config+lang+base) → membank → chunk. Драйвер импортит всё (композит-корень, как crush internal/agent). Форм-фиксы оркестратора (Export/RequestHash/resolveChunkState) едут в тот же пак — golden ревьюится ОДНИМ слоем.
Приложение B — предлагаемая экспорт-поверхность (что капитализируется / что прячется)
internal/text(база):NormalizeSourceKey,RunesEqual,TokenizeCyrillic. (сейчас memnorm/mempostcheck; общие для miner+membank+checks).internal/pipeline/model(база):Chunk,MinerChunk,SegBudget,Document(value-типы, вокабуляр).miner: ЭКСПОРТMineBank,MinerConfig,MinedTerm,Contrast,LoadContrast; ПРЯЧЕТ mineDetect/proposeAliasEdges/buildPalladiusCyrSyllables/patternCandidates/emissionEligible. Импорт: lang, store, text, model.membank: ЭКСПОРТMemoryBank,Select,Version,BaseVersion,MemoryEntry, инъекц-рендереры; ПРЯЧЕТ pickedEntry/Aho-Corasick/suppressContained. Импорт: lang, store, text.chunk: ЭКСПОРТSplitChunks,Ingest,IngestEncoded; ПРЯЧЕТ chapterDraftChunks/packSentences/splitSourceSentences. Импорт: lang, model.checks: ЭКСПОРТRunCheapGates(+CheapGateConfig/CheapGateResult),SanitizeOutput(+SanitizerResult),CompileCheckers(+Checkers); ПРЯЧЕТ lint*-методы/dcCheckers-внутренности. Импорт: config, lang, text.
ДОПРИЁМОЧНАЯ ДЕЛЬТА (лендинг-блокер оркестратора, 24.07)
(1) ОБЯЗАТЕЛЬНО — аддендум parsePalladius ВЫПОЛНЕН. (а) generic-парсер parseCategoryRows → map[категория]map[key]value (3-field key→cyr, 2-field key→"" set-member); НЕТ per-category switch, незнакомая категория ≠ ошибка парсера. (б) ОДИН типизированный Palladius-struct (Initials/Finals/YW/SpecialI + Retroflex/VFinal/VFinalInitial) вместо 4-картежа + 7 параллельных Pack-полей → Pack.Palladius Palladius. (в) required-категории валидирует ПОТРЕБИТЕЛЬ (validate()), не парсер. Удалены parsePalladius+parsePalladiusPhonotactics; assignPair/mergePair схлопнуты в parse+merge (оба пар-файла через generic-путь, union нил-сейф через newPalladius()); потребители (miner_palladius.go, langpack_test.go) обновлены. Hash-нейтрально (байты .txt не тронуты); packAlgoVersion v1→v2 (схемо-изменение по политике константы — выбрал БАМП; сдвиг Version() = version-only, golden без пака не тронут).
(2) Хвосты: pipeline-c2.yaml — явный segmentation-блок (1797/3200/1.1978/0.3852, байт-нейтрально, закрыл обещание коммента pipeline.go «все шиппинг ставят явно») · backend/README.md:59 пути промптов → prompts/zh-ru/ · embedded.go parseCJKSection unknown-category want-list → +magnitude · packAlgoVersion бамп (см. выше).
(3) НЕ тронуто (кандидаты пака-15, по указанию оркестратора): fail-loud оверлея уровнем выше · override-семантика unionStringMap · isRuTarget/'ru'-швы · empty-probe гард lintMagnitudeScale · дуп терминаторов chunker/coverage · 第.
Верификация дельты: go build/vet/test -race зелёные · golden БАЙТ-ИДЕНТИЧЕН (capture.golden не тронут) · парити EXACT n=13618 {方源:0 蛊:1 蛊师:2 古月:22}. Сессия НЕ коммитит.