diff --git a/docs/PROGRESS.md b/docs/PROGRESS.md index ead7fb4b..83f666ac 100644 --- a/docs/PROGRESS.md +++ b/docs/PROGRESS.md @@ -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 — форма решения и почему именно она.** Источник объявляет НОЛЬ каналов явной строкой +`channelnone` (`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.1–3.2 — взято МЕНЬШЕЕ, то есть безопасная сторона (уже окно, меньше батч). +Значения `kwic_per_term 3 · kwic_width 110 · basis_width 110 · batch_runes 16400`; все четыре выписаны +ЯВНО, потому что недоназванный `basis_width` превращает свой первый тюнинг в пере-покупку банка из +ПОЖИЗНЕННОГО бюджета роли. `packAlgoVersion` НЕ бампнут (ни один пак в дереве `terminology.txt` не несёт ⇒ +ни одна существующая байта не читается иначе); условие протухания этого вывода записано у самого ключа. + +**§4.3 — движок доносит РАЗМЕТКУ, вердикта не выносит.** Носитель курсива в книге один: ``, +тегов ``/`` — ноль, правило в 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` оставляет непарный глиф ЛИТЕРАЛОМ и не производит несбалансированный ``, иначе 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 НЕ делалась: прогон отложен