Record the second-pair reachability pack report written by the backend session in its own journal section

This commit is contained in:
heaven 2026-09-18 06:49:40 +03:00
parent 9defda4918
commit e6f9a3bdb6

View file

@ -210,6 +210,245 @@
## Бэкенд
#### ОТЧЁТ пака «ДОСТИЖИМОСТЬ ПАР-ДАННЫХ ДО ХОЛОДНОГО ПРОГОНА» (18.09, сессия `textmachine-main-c8`). НЕ КОММИЧУ — дерево передаю оркестратору №23
**Деньги пака: $0.** Платных вызовов моделей — ноль. Живые пробы движка гонялись на боевом
`configs/pipeline-c1.yaml` БЕЗ единой правки конфига, с фиктивными ключами в окружении и книжным потолком
`ceilings.book_usd: 0.000001`, при котором первая же резервация отказана ДО обращения к провайдеру
(`denied estimate=$0.013402, ch1/chunk0/draft`, `run_usd=0.000000`, `committed=$0 reserved=$0`).
`.env` не читался.
**Предмет пака — не «починить английскую книгу», а сделать данные ВТОРОЙ пары достижимыми.** Судья каждого
решения: заработает ли пара, которой в репозитории ещё НЕТ, без правки Go.
| пункт | исход | чем предъявлено |
|---|---|---|
| §4.1 достижимость пар-пака | **сделано** | `tmctl translate` на боевом конфиге: ДО — `EXIT=10`, «gates.terminology is enabled but this book cannot mine a bank… currently absent»; ПОСЛЕ — пак грузится, ингест 71 глава / 386 чанков, стартует черновая волна, остановка потолком до первого вызова |
| §4.2 сайзинг терминолога | **сделано** | четвёртый ключ `batch_runes` заведён в пар-файл; множитель 2.74 измерен приборами движка на обеих боевых книгах |
| §4.3 курсив на провод | **сделано** | 4842 носителя доезжают до чанка на книге прогона (счёт глифа в тексте глав и чанков движком); экспорт — обе поверхности |
| §4.4 пар-связанные ключи брифа | **сделано** | словарь брифа объявляет ПАРА, книга выбирает имя, Go не знает ни одного; книга из шаблона деплоя (`palladius`) получает `EXIT=10` до первого цента, $0-чтение той же книги живо |
| §4.5 упор в баланс провайдера | **сделано наполовину, вторая половина названа** | у исчерпания кредитов есть имя (`provider_credits_exhausted`) в последней строке прогона и в журнале; НОВОГО КОДА ВОЗВРАТА и нового слова в словаре кадров НЕ добавлено — это замороженные швы |
| §4.6 регистровые склейки ключей банка | **не делаю, довод ниже** | данные уже заландены прошлым паком; обе Go-дороги двигают ГЛОБАЛЬНУЮ ось и пере-покупают китайскую книгу |
---
**§4.1 — форма решения и почему именно она.** Источник объявляет НОЛЬ каналов явной строкой
`channel<TAB>none` (`configs/langpacks/en/manifest.txt`). Молчаливое «пустой файл = ноль каналов» отвергнуто:
пустой манифест и ОБРЕЗАННЫЙ имеют одни и те же байты, и вывод из пустоты сделал бы недописанный файл тихо
инертным паком. Файл, который не утверждает ничего, по-прежнему отказ. Каталог пары непуст (`terminology.txt`),
иначе git его не хранит, а `loadLangPack` включается по существованию каталога (`runner.go:436`).
**Поправка к промту, найденная исполнением:** «детерминированный заголовок главы открывается даром» —
НЕВЕРНО. `stripHeading` (`chunker.go:165`) требует ДВУХ половин: пар-шаблон И грамматику заголовка
ИСТОЧНИКА, а у латиницы её нет (ряд 303); заголовки книги прогона — голые римские цифры внутри документов,
`heading` непуст у 0 из 71 глав. `heading.txt` НЕ заведён: он дал бы артефакт без единой смены поведения.
**§4.2 — множитель ИЗМЕРЕН, а не выбран.** Прибор — сам движок (`tmctl manifest --json`, суммы
`source_chars_dense/_sparse` по всем юнитам): zh (蛊真人, 2283 главы) dense 6 191 523 + sparse 937 761 →
**0.9123 токена на руну**; en (книга прогона, 71 глава) dense **0** при sparse 1 310 510 → **0.3333**;
отношение **2.7369**. Контроль, что мерили не пустоту: у английской книги dense-рун ноль ИЗ 1 310 510
прочитанных. Независимый прибор (калибровка токенизаторов, `experiments/01`: 0.86 ток./иероглиф и
3.64 знака/токен) даёт 3.13.2 — взято МЕНЬШЕЕ, то есть безопасная сторона (уже окно, меньше батч).
Значения `kwic_per_term 3 · kwic_width 110 · basis_width 110 · batch_runes 16400`; все четыре выписаны
ЯВНО, потому что недоназванный `basis_width` превращает свой первый тюнинг в пере-покупку банка из
ПОЖИЗНЕННОГО бюджета роли. `packAlgoVersion` НЕ бампнут (ни один пак в дереве `terminology.txt` не несёт ⇒
ни одна существующая байта не читается иначе); условие протухания этого вывода записано у самого ключа.
**§4.3 — движок доносит РАЗМЕТКУ, вердикта не выносит.** Носитель курсива в книге один: `<span class="italic">`,
тегов `<i>`/`<em>` — ноль, правило в CSS одно (пере-снято мной: 126 документов, 2 CSS-файла, класс `.italic`).
Глиф — звёздочка, и выбор измерен: литеральных `*` в прозе книги **0 при 1 588 694 прочитанных знаках**.
Замер сквозной, прибором движка: **9684 звёздочки = 4842 носителя** в тексте глав И в тексте чанков,
ровно столько, сколько курсивных носителей в HTML; прирост объёма **+0.604 %**.
**Собственная ошибка метода, названная:** первый счёт (по сумме `source_chars` двух манифестов) дал 4840 —
суммы снимались на РАЗНЫХ нарезках (379 против 381 юнита), где границы юнитов подрезаются иначе. Виноват был
прибор, не движок; прямой счёт глифа снял вопрос.
Версионирование — по ратифицированной форме опциональных пар-файлов (условный фолд через `pack.Version()`),
константа нарезки НЕ тронута; три условия оркестратора выполнены: файл УТВЕРЖДАЕТ глиф как контракт с
промтами пары, байт-равенство для необъявившей пары предъявлено на EPUB-фикстуре С КУРСИВОМ, остаток назван
(правка самого алгоритма маркера при уже объявившихся парах не двигает ни файла, ни версии пакета —
закрывается только дисциплиной бампа `packAlgoVersion`).
**Четыре прибора, которые считают текст, и величина сдвига у каждого:** оценка токенов +0.604 % (сторона
безопасная — больше резерв); коридор `len_ratio` — маркеры есть по обе стороны, сдвиг ≈0; доля письма
исходника (`sourceScriptShare`) — знаменатель считает ВСЕ руны, латинская доля падает на ~0.6 % относительно
при замеренном запасе к порогу 11×; плотность (`DenseSparseCounts`) — +0.6 % к sparse.
**Наблюдаемость:** `italic_carriers` печатается в нотах ингеста ДАЖЕ ПРИ НУЛЕ, если пара объявила маркер —
именно ноль здесь есть находка (CSS-формы, которые сканер принимает, узки намеренно).
**§4.4 — множество политик объявляет ПАРА.** `configs/pairs/<пара>.yaml` → `brief: {transcription: {default,
allowed}, honorifics: …}`. Книга без ключа получает пар-умолчание, и оно пишется В КНИГУ до вычисления
`brief_hash` ⇒ правка умолчания — громкий `--resnapshot`, а не тихая смена каждого запроса (это и был главный
довод против дома в пар-слое: он не фолдится ни в один снапшот). Имя, которого пара не знает → отказ на
ПИШУЩЕМ пути, предупреждение на $0-читающем (D20.4). `zh-ru` словаря НЕ объявляет НАМЕРЕННО: объявление дало
бы её книгам без ключа новое значение на проводе. ⚠ Платформенная половина (пар-связанные ключи в операторском
шаблоне) — чужая зона; по замеру оркестратора шаблон есть артефакт ОПЕРАТОРА, поэтому блокером прогона это не
является, но пример в рецепте учит неверному — пинг зоне платформы.
**§4.5 — что сделано и что НЕТ.** `llm.CreditsExhausted(err)` — один предикат над типизированной ошибкой
транспорта, читающий ТЕ ЖЕ маркеры, что и политика ретраев (402 · 429 с `insufficient_quota`/`quota_exceeded`),
поэтому «кредиты кончились» не может разъехаться между двумя местами. Драйвер называет эту причину машинным
токеном в последней строке прогона и ERROR-записью. **НЕ сделано и почему:** ни нового кода возврата
(`exitCode` сам называет свою полосу замороженным швом: «a fresh code would be a word added to a ratified
dictionary»), ни нового слова в словаре `runevents.finished`обе вещи читает платформа, и расширение шва
есть решение, а не правка пака. ⇒ человек получает названную причину, ПРОГРАММА по-прежнему видит родовое
терминальное падение, и ряд **502** остаётся открытым ровно на эту половину.
**§4.6 — Go-гард НЕ строю, и вот довод вместе с остатком.** Данные уже заландены прошлым паком: и
`prompts/en-ru/terminologist.md`, и банкнотная вставка несут явное правило про одиночное заглавное
нарицательное со строчным омографом (плюс этим паком добавлено правило «звёздочки разметки в термин не
входят»). Детерминированных дорог в Go я вижу две, и обе двигают ГЛОБАЛЬНУЮ ось: правка `NormalizeSourceKey`
двигает `text.NormVersion()` (фолдится в ключ манифеста безусловно — `manifest.go:282,:384`), правка матчинга
двигает `matchVersion` (пишется в `ComputeVersionScopedIn` безусловно — `membank/memory.go:417`). ⇒ цена любой
из них — пере-снапшот и пере-покупка КИТАЙСКОЙ книги за дефект, которого у неё нет по построению (у Han нет
регистра). **Это не довод держать дефект, а причина, по которой решение не моё:** оно требует слова владельца
о цене и о том, ЧТО делать с коллизионным термином (отбросить · пометить AMBIGUOUS · отдать владельцу в
стоп-таблицу). ⭐ Форма, которую я предлагаю и которая ГЛОБАЛЬНУЮ ось НЕ двигает: гард на СБОРКЕ банка, а не
на матчинге — предикат «одиночная поверхность с заглавной, чей строчный омограф встречается в исходнике
книги» инертен для Han по построению, а версия банка есть хеш его СТРОК, поэтому для китайской книги, где
предикат не срабатывает ни разу, она не двигается. Остаток честный: пока гарда нет, дисциплина промтов —
инструкция МОДЕЛИ, а не детерминизм.
---
**⛔ НАХОДКА, КОТОРОЙ В ПАКЕ НЕ БЫЛО, И ОНА ДЕНЕЖНАЯ: лейбл промта был ОБЩИЙ НА ВСЕ ПАРЫ.**
`prompt_version` фолдится в снапшот (`snapshot.go:310`, свёртка `:495`), а ран-конфиг объявляет его ПО
СТАДИИ — один на каждую пару, которую этот конфиг обслуживает (в дереве их две). ⇒ до этого пака правка
промтов ОДНОЙ пары ставила перед выбором: бампнуть общий лейбл — и пере-снапшотить, то есть пере-купить,
книги ВСЕХ остальных пар, чьи байты не двигались; либо оставить лейбл — и держать одно имя над двумя разными
текстами, ровно то, что ловит реестр лейблов. Встретилось не в теории: абзац о маркере курсива покрасил три
лейбла `en-ru/*`. **Лечение: лейбл стал ПАР-СКОУПНЫМ**`configs/pairs/<пара>.yaml``prompt_versions`,
ключ = базовое имя файла по конвенции; ран-конфиг по-прежнему обязан свой лейбл назвать, пара только заменяет
СВОЙ. Предъявление: дифф реестра `testdata/prompt-labels.json`**три строки, все `en-ru/`, ни одной `zh-ru/`**.
**КИТАЙСКАЯ ПОЛОВИНА НЕПОДВИЖНА — три независимых свидетеля, снятых ПОСЛЕ последней правки backend/:**
1. ключ манифеста китайской книги `ac9c075ac5bfd0b6f56124f7a389cfb6a26e96aab0b50a86f0d5e02c0032f143` — тот же,
что до первой правки пака (он сворачивает `chunker_version` · сегментацию · `langpack_version` ·
`embedded_version` · `norm_version` · структуру, то есть все глобальные оси разом);
2. `TestGolden*` зелёные без ре-капчура — провод байт-идентичен;
3. в диффе реестра лейблов промтов ни одной китайской строки.
⚠ Это свойство ОБЕСПЕЧЕНО, а не случайно: пар-данные в `zh-ru` не добавлены (ни разметки, ни словаря брифа,
ни сайзинга), константы версий не тронуты, а ингест EPUB китайская книга не проходит вовсе — она `.txt`.
⚠ И то, чего это НЕ доказывает, названо тестом, а не словами: диспетчер ингеста ходит по РАСШИРЕНИЮ файла, а
не по паре, поэтому «китайская книга не дойдёт до маркера» есть свойство СЕГОДНЯШНЕЙ КНИГИ, а не пары —
`TestAPairThatDeclaresNothingIsByteIdentical` предъявляет байт-равенство на EPUB-фикстуре С КУРСИВОМ.
**ОБСЛУЖИВАНИЕ ТЕСТОВ, КОТОРОЕ ОБЪЯВЛЯЮ** (правка вызвана ЗАКАЗАННОЙ сменой поведения, не «чтобы прошло»):
1. `testdata/prompt-labels.json` — три строки `en-ru/` пере-записаны штатным `TM_UPDATE_PROMPT_LABELS=1`;
гарантия не уехала никуда: лейблы стали пар-скоупными, и реестр теперь утверждает то же самое о новых именах.
2. `testdata/operator-messages.txt` — две новые операторские фразы внесены в каталог (отказ по словарю брифа
на $0-пути и имя исчерпанных кредитов). Это штатная точка ревью формулировок, а не обход гейта.
3. `chunk.IngestEncoded` и `extractXHTML` получили параметр пар-разметки ⇒ в тестовых вызовах дописан `nil`
(16 мест в `internal/chunk`, 2 в `internal/pipeline`). При `nil` поведение то же, что было, и это
утверждение — сам предмет `TestAPairThatDeclaresNothingIsByteIdentical`.
4. `Document` получил счётчик `ItalicCarriers`, и рефлексивный гард `TestEveryIngestCountReachesTheAlarm`
потребовал, чтобы он доезжал до оператора, — требование исполнено, а не ослаблено.
**ГЕЙТ ЗОНЫ, числа сняты ПОСЛЕ последней правки `backend/`:** `make battery` (`build · vet` оба тег-набора +
архитектурные анализаторы · `gofmt` · `golangci-lint` · `go test ./... -race`) — **MAKE_EXIT=0, строк `FAIL`
ноль**. Полнота сверена СПИСКОМ, а не чтением хвоста: `go list ./...` даёт 24 пакета, вердиктов в логе 24,
`comm -23` пуст и `comm -13` пуст тоже. `ok` — 20, `[no test files]` — 4.
**Пропущено 6 тестов, все — корпусные, на чистом клоне тёмные:** `TestMinerFullBookParity` ·
`TestProbeBankBasisM1` · `TestProbeBankBatchOrdinalShift` · `TestCorpusBankKeyConflicts` ·
`TestHelperEventsRun` · `TestHelperKillLoop`.
⚠ После батареи правились только `docs/PROGRESS.md` и каталог мутаций — ни одной целью гейта они не читаются
(контроль прибором: упоминаний `PROGRESS` в Go-файлах 9, ВСЕ — проза комментариев, чтений файла 0;
`mutations.json` читает ровно один файл `cmd/tmmutate/main.go`, тестов среди читателей 0 при 49 Go-файлах,
упоминающих `battery`).
**ЧТО В ЭТОМ ПАКЕ НЕ ПРОВЕРЕНО НИКЕМ И ГДЕ ПРИБОР СЛЕП** (обязательная секция; первое — важнее остального):
**ВСЯ ЦЕПЬ §4.3 НИ РАЗУ НЕ ВИДЕЛА ЖИВОЙ МОДЕЛИ.** Пак $0 по построению, поэтому измерено ровно одно
направление: исходник → маркер → чанк → (обратно) экспорт. **Вернёт ли модель маркеры на месте — не
измерено ни разу**, и это единственное звено, которое нельзя проверить бесплатно. Формы отказа, к которым
дерево готово: маркеры потеряны (экспорт отдаст текст без курсива — потеря, не порча), маркеры непарны
(`emphasisSpans` оставляет непарный глиф ЛИТЕРАЛОМ и не производит несбалансированный `<i>`, иначе EPUB не
открылся бы вовсе), маркеры съехали на соседние слова (лечит редакторский промт — он это прямо велит
проверять). ⇒ **первую главу боевого прогона стоит прочитать глазами именно на этот предмет.**
**CSS-сканер узок НАМЕРЕННО и об этом молчать нельзя:** он принимает правило, чей селектор — один класс,
и не знает каскада, наследования, `@media` и сокращения `font: italic`. Книга, выражающая курсив иначе,
получит НОЛЬ носителей — и именно поэтому `italic_carriers` печатается даже при нуле.
**KWIC-контексты терминолога несут маркеры** (движок их не срезает). Вреда не замерено: список терминов
строит движок, а не модель, и правило первого поля в банкноте прямо велит писать термин без звёздочек. Если
замер покажет иначе, срезать надо на СБОРКЕ KWIC, а не правилом в промте.
**Качество значений английской пары не измерено и этим паком измерено быть не могло:** размеченного
корпуса en→ru в репозитории нет. Мои четыре числа сайзинга ВЫВЕДЕНЫ из свойства письма и предъявлены
выводом, а не проверены на выходе модели. Батарея зелена при любом их содержании — единственный рубеж
содержимого здесь довод, а не гейт.
**Класс §4.4 закрыт для пар, которые ОБЪЯВЯТ словарь, и открыт для тех, кто не объявил** — в том числе для
`zh-ru` в этом паке (объявление двигало бы её провод). Японская книга на `zh-ru`-шаблоне по-прежнему получит
`palladius`, если её пара словаря не заведёт.
**Наблюдение о самом гейте, не о паке:** `golangci-lint` в логе батареи печатает предупреждение о файле
из ЧУЖОГО дерева (`/tmp/tm-verify-0509/...`, его на машине больше нет) — след кэша соседней сессии.
Вердикт цели при этом `0 issues`, и мои файлы линтер видел (ранние прогоны ловили на них `gofmt`).
**ЧТО НЕ ПОЛУЧИЛОСЬ.** Пере-снять «4842 против 4840» суммой `source_chars` двух манифестов не удалось бы
никогда — метод негоден по построению (разные нарезки), и понял я это только сменив прибор. Отдельно:
§4.6 остался без детерминированной половины, и это не «не успела», а «не моё решение» — цена обеих Go-дорог
есть пере-покупка китайской книги, и предлагать её должен тот, кто вправе тратить.
**РЯДЫ, КОТОРЫЕ ПРЕДЛАГАЮ ЗАВЕСТИ ИЛИ ОБНОВИТЬ** (пишет оркестратор):
1. **347** — закрыт: ноль каналов объявляется, вторая ИСХОДНАЯ пара грузится, предъявлено прогоном.
2. **272** — движковая половина закрыта (словарь брифа пары + отказ до траты); платформенная половина —
пинг зоне платформы: пример в операторском рецепте учит пар-связанному ключу.
3. **500** — закрыт замером и починкой: 4842 носителя доезжают до чанка, обе экспортные поверхности отдают.
4. **502** — ПОЛОВИНА: причина названа человеку; отдельного исхода для ПРОГРАММЫ (код возврата / слово в
словаре кадров) нет, и это упирается в замороженные швы.
5. **НОВЫЙ РЯД:** регистровые склейки ключей банка на письменности с регистром — детерминированный гард на
СБОРКЕ банка (форма предложена выше), цена обеих альтернативных дорог названа.
6. **НОВЫЙ РЯД:** KWIC терминолога несёт маркеры разметки — замерить влияние на боевом прогоне, по итогу
либо срезать на сборке, либо закрыть с доводом.
7. **303** остаётся открытым и этим паком не тронут: безъюнитная грамматика по-прежнему не режет книгу, и
именно поэтому английская книга не получает детерминированного заголовка главы.
**МУТАЦИИ — ТРИ ИСХОДА, и третий пуст честно.** Посажено 9 мутаций, каждая ВВЕДЕНА В ГЕЙТ
(`cmd/tmmutate/mutations.json`, `battery: true`; в каталоге стало 547 записей, в гейте 336). Прогон
инструментом на отдельной копии:
| исход | сколько | детали |
|---|---|---|
| **поймано (RED)** | **9 из 9** | каждая названа ловящими тестами инструментом; текст падения читался руками при ручной посадке, а не только цвет |
| **выжило** | **0** | — |
| **НЕ ИЗМЕРЕНО** | **0** | базовые прогоны всех четырёх затронутых пакетов зелены до посадки, ни одной несобравшейся команды |
Ловящие тесты по записям: `SP-source-cannot-declare-zero-channels``TestASourceMayDeclareNoChannelAtAll`,
`TestTheShippedSecondPairLoads`; `SP-pair-batch-bound-never-reaches-the-engine` и
`SP-shipped-en-pair-sizing-equals-the-engine-default``TestTheSecondPairSizesItsOwnTerminologyCalls`
(вторая посажена в ДАННЫЕ, потому что пин стоит над данными — мутация Go мерила бы другой слой);
`SP-epub-italics-not-carried-to-the-chunk``TestADeclaredPairCarriesTheEmphasis` +
`TestTheWalkerSurvivesTheMarkupRealBooksShip`; `SP-epub-export-drops-the-emphasis` и
`SP-txt-export-drops-the-emphasis``TestEmphasisSurvivesTheWholeCircle`;
`SP-provider-credits-lose-their-name``TestARunStoppedByProviderCreditsSaysSo`;
`SP-brief-policy-of-the-pair-judges-nothing``TestTheBriefPolicyOfAPairRefusesAnotherPairsName`;
`SP-pair-scoped-prompt-label-ignored``TestAPairLabelsItsOwnPromptsWithoutMovingAnother`.
**И гейт поймал МОЮ правку, а не только мои посадки.** Статический обход якорей по ВСЕМУ каталогу
(547 из 547) нашёл **одну** сгнившую запись: `EN-banknote-body-drifts-from-the-translator-it-copies`
целится в sha реестра лейблов, а я этот реестр пере-записала под пар-скоупные имена. Запись пере-нацелена
НА ТО, ЧТО УТВЕРЖДАЕТ ЕЁ ПРОЗА (её собственный комментарий предупреждает: «both anchors are VALUE-coupled»),
новые значения взяты пересчётом канонической формы промта и проверены ИСПОЛНЕНИЕМ — пере-прогоном этой
записи инструментом, а не тем, что линтер перестал жаловаться.
**Чего я НЕ прогнала и это надо знать:** полное подмножество гейта (336 записей) в этом паке НЕ
пере-прогонялось — по замеренному темпу это многочасовая цель, намеренно не входящая в `make battery`
(README зоны говорит это прямо). Прогнаны: мои 9 по `-id` + полный СТАТИЧЕСКИЙ обход якорей 547/547.
**ФАЙЛЫ ПАКА.** Код: `internal/lang/langpack.go` · `internal/chunk/{ingest.go,inlinemarkup.go}` ·
`internal/bookfile/{model.go,epub.go,txt.go}` · `internal/config/{pair.go,pipeline.go}` ·
`internal/pipeline/{runner.go,events.go,terminologist.go,stagerun.go,bookbuild.go}` ·
`internal/llm/httpllm.go`. Данные: `configs/langpacks/en/manifest.txt` (новый) ·
`configs/langpacks/en-ru/{terminology.txt,inline-markup.txt}` (новые) · `configs/pairs/en-ru.yaml`.
Промты: `prompts/en-ru/{translator.md,translator-banknote.md,editor.md}`. Тесты: 4 новых файла
(`internal/chunk/inlinemarkup_test.go` · `internal/pipeline/{secondpair_test.go,providercredits_test.go}` ·
`internal/config/promptlabel_pair_test.go`) + дописано в `internal/lang/langpack_test.go` и
`internal/config/pairlayer_enru_test.go`. Носители: `backend/README.md` ·
`backend/docs/EN_RU_PAIR_BASIS.md` (§13 — что пара везёт и чего у неё нет) ·
`cmd/tmmutate/mutations.json` (+9 записей, одна пере-нацелена).
**Работа завершена, править не планирую.**
#### ОТЧЁТ пака «АНГЛИЙСКАЯ ПАРА en→ru» (18.09, сессия `textmachine-main-c5`). НЕ КОММИЧУ — дерево передаю оркестратору №23
**Деньги пака: $0.** Платных вызовов моделей — ноль. Дымовая покупка §4.10 НЕ делалась: прогон отложен