diff --git a/docs/experiments/23-editor-tier.md b/docs/experiments/23-editor-tier.md index dd26457e..06ac8c44 100644 --- a/docs/experiments/23-editor-tier.md +++ b/docs/experiments/23-editor-tier.md @@ -3982,3 +3982,351 @@ DeepSeek, отношение от пина не зависит, обе пары, ⛔ **Открытый денежный вопрос:** 12 клеток умерли по таймауту и записаны с нулевой ценой; списал ли вендор токены за оборванное соединение, по диску не определить. Потенциально невидимый кассе расход $0.1–0.3. + +--- + +## Д32 — ⭐ ПАНЕЛЬ-0: «АРХИТЕКТУРА × СЛАБЫЙ ЖИЛЕЦ». ПРЕ-РЕГ, ЗАПИСАН ДО СБОРКИ ПАКЕТОВ + +> ⚠ **Номер Д31 намеренно пуст и зарезервирован** за вердиктом по вендорам: планом 22.08 (§7 п.6) +> он выдан Шагу 2 — второму чтению панели `vendor2`, — и до метрики (ii) того шага вердикт печатать +> запрещено. Дыра в нумерации есть бронь, а не потерянная секция. + +Замер отвечает на **минимаксный вопрос владельца** дословно: «даже на худших вендорах наша +архитектура должна отрабатывать лучше, чем худшие вендоры на другой архитектуре». На диске лежит +природный эксперимент, за который уже заплачено: один и тот же жилец `glm-5` работает на одних и +тех же 16 английских главах в ДВУХ топологиях — редактором поверх боевого черновика (`E6`) и +однопроходкой (`RG`). Панель $0. + +### Д32.0 ⛔ БЛОКЕР СБОРКИ, КОТОРЫЙ ПРИШЛОСЬ СНЯТЬ ПЕРВЫМ + +`rol.py` арма `E6` **не знал**: единственное его вхождение в файле было комментарием об эррате. +Клетки `dv-g-e6-*` куплены другим ригом (`en_axis.py --e6`) из кассы **ФД-G**, лежат под буквой +чужой фазы и несут ДРУГУЮ схему — нет полей `pair`, `podacha`, `gen`, зато `role="editor3"`. + +**Чем это было опасно, и это ровно класс «реализация не то, чем названа».** Неизвестное имя арма +падало в последнюю ветку `read_texts` (`ZK.cell(ZK.tag(…))`), та строила несуществующий путь +`dv-j-e6-`, файла не находила и возвращала **пустую строку**; `emit_read` выбрасывает главу, +у которой пуст хоть один арм. Команда `--emit-read --panel=RG,E6,…` не упала бы и не соврала бы +вслух — она собрала бы панель из скольких-то глав, и число это зависело бы от того, чьи файлы +случайно нашлись рядом. + +**Починка** (`rol.py`): заведён реестр `FOREIGN` — армы чужих фаз со своим префиксом, кассой, +ригом-владельцем и ожидаемыми полями клетки; загрузчик `foreign_text` на любой беде даёт **СТОП**, +а не пустую строку; чистая функция `foreign_defect` проверяет клетку **по содержимому**, а не по +имени файла (имя мы строим сами, оно не удостоверяет ничего): `arm` · `uid` · `role` · модель · +`finish=stop` · непустой `content`. Единая точка `arm_text` перечисляет все четыре реестра, и имя, +не известное ни одному, роняет сборку — прежде это была тихая пустая строка. + +**Гейты проверены ФАЛЬСИФИКАЦИЕЙ, а не зеленью.** Селфтест кормит гейт шестью заведомо больными +клетками, полученными мутацией настоящей: чужой арм · чужая глава · чужая роль · чужая модель · +`finish=length` · пустой `content`. Отдельно проверено, что при обезвреженном `foreign_defect` +селфтест краснеет на шести пунктах, при снятой проверке пары — на одном, при возврате пустой +строки вместо СТОПа — на одном. Гейт, зелёный только на здоровом входе, не сторожит ничего: ровно +этим болел селфтест блокера Б8 — он фильтровал арм по наличию файла клетки, файлов не было, и +гейт зеленел вхолостую. + +### Д32.1 СОСТАВ ПАНЕЛИ И ЗАМОРОЖЕННЫЙ СПИСОК ГЛАВ + +Тег панели **новый**; существующие теги не пере-эмитируются (пере-эмиссия с другим составом армов +переписала бы раскладку уже прочитанной панели, и ответы стали бы мусором молча). + +| арм | что это | модель | промт | потолок вывода | клеток | +|---|---|---|---|---|---| +| `ZD` | голый черновик | `deepseek-v4-flash` | translator, 3268 зн. | 32000 | 16/16 | +| `Z0` | черновик → боевой редактор | `deepseek-v4-pro` | editor, **4404 зн.** | **16000** | 16/16 | +| `ZF` | он же, ВТОРАЯ генерация (пол) | `deepseek-v4-pro` | editor, **4404 зн.** | **32000** | 16/16 | +| `E6` | черновик → редактор `glm-5` | `glm-5` | editor, **4404 зн.** | **16000** | 16/16 | +| `RG` | однопроходка-роль | `glm-5` | onepass, 7909 зн. | 32000 | 16/16 | + +⭐ **Системный промт `Z0`, `ZF` и `E6` — ПОБАЙТНО ОДИН** (сверено исполнением). Значит: +* `Z0 ↔ E6` — **чистый контраст жильца**: топология, промт, вход и черновик тождественны, меняется + только модель; +* `Z0 ↔ ZF` — **пол**: тот же запрос, вторая генерация; +* `E6 ↔ RG` — **контраст топологии при одном жильце**, тот самый минимаксный. + +Шестнадцать глав — пересечение, полное у всех пяти армов. Список заморожен ДО чтения (порядок — +детерминированный отбор захода Д17): + +``` +f2274720c9 53f1a12dff b065a92dc0 26c3bff1d4 49ca859c94 100b088f71 197f98eb61 d3237e1dea +eefdade2c3 27cb3a7e69 3bd6481182 8e50448cea 90a20cb443 001e6ac4eb c3517980c7 5a8f48d24a +``` + +**Объём: 26 243 знака исходника = 7.89 главы Гу.** Панель бесплатная и потому идёт на 7.89, а не +на стандартные 6 глав Гу: стандарт заведён для ПОКУПАЕМЫХ ранговых панелей. За все 80 клеток уже +заплачено $0.906 (`ZD` 0.016 · `Z0` 0.124 · `ZF` 0.668 · `RG` 0.046 · `E6` 0.052). + +### Д32.2 ШАПКА: ЖИЛЕЦ УРАВНЕН, И УРАВНЕН МЕХАНИЗМОМ, А НЕ СОВПАДЕНИЕМ + +Сверено по клеткам, 16 из 16 у обоих армов: модель `glm-5` (и `model_returned` та же) · +`finish=stop` · **`reasoning_tokens=0`**. + +⚠ И причина нуля названа кодом, а не наблюдением: у `RG` объявленный уровень `THINK_LEVEL["RG"] += "off"`, то есть подавление ростера остаётся; `E6` покупался прямым `ROSTER.call_kwargs` без +переопределения. На проводе у обоих **`extra_body: {"thinking": {"type": "disabled"}}`** — +одно и то же наше подавление. Это блокер Б7 в обоих армах СРАЗУ, и именно поэтому он их не +разводит: конфаундер общий. `temperature: 0.3` у обоих; честно ли Z.ai её принимает — по-прежнему +НЕ ПРОВЕРЕНО (дыра ревью §4). + +### Д32.3 ⛔ ЧТО В ЭТОЙ ПАНЕЛИ НЕ УРАВНЕНО — НАЗЫВАЕТСЯ ДО ЗАМЕРА, А НЕ ПОСЛЕ + +1. **Объём инструкции. `RG` 7909 знаков против 4404 у `E6` — ×1.80.** Контраст топологии + неизбежно несёт на себе и промт: у однопроходки и у редактора не может быть одного промта. + ⇒ читать вывод только так: «топология ВМЕСТЕ с её промтом». Направление конфаундера играет + ЗА однопроходку (в эксп-21 разница объёма ×1.92 работала на длинный промт), поэтому проигрыш + `RG` был бы выводом СИЛЬНЕЕ объявленного, а выигрыш — слабее. +2. **⛔ Потолки вывода РАЗНЫЕ, и это новая находка, ревью 21.08 её не несёт.** `Z0` и `E6` куплены + под 16000, `ZF` и `RG` — под 32000. Асимметрия внутри самой пары пола `Z0/ZF`. Обрывов нет + (все `finish=stop`), но **у `Z0` максимум `completion_tokens` = 15 835 при потолке 16 000 — + 99.0%**: распределение длины размышления у половин пола цензуровано по-разному. Селфтест + захода, объявленный сторожем («ZF = ТОТ ЖЕ запрос, что у боевой связки»), сличает только + `msgs` и к телу вызова слеп — тот же класс В7. +3. **`RG` черновика не видит вовсе** — он однопроходка. «Буфер» здесь означает не «второй проход», + а «дорогая чужая модель сделала черновик, а `glm-5` только правил». +4. **Цена клетки `ZF` впятеро выше `Z0`** при том же промте и модели — следствие ценового пина + DeepSeek (Б11), а не свойство арма. Замера не касается: панель бесплатна. +5. **Ни `E6`, ни `RG` не хранят `call_kwargs` и `reasoning_text`** — провенанс восстановлен по + коду покупки и по токенам, прямого доказательства провода на диске нет (долг Шага 6). + +### Д32.4 ПЕРВИЧНЫЙ ЭНДПОЙНТ — ДЕФЕКТ-КЛАССЫ, А НЕ МЕСТА + +**Почему не места.** Мощностная таблица консилиума 22.08: на английской паре эффект в ОДНО место +стоит 68 глав Гу, в половину места — 271. Панель-0 — 7.89. ⇒ **ранговый эндпойнт этой панели +объявлен ОПИСАТЕЛЬНЫМ ЗАРАНЕЕ**, до всякого числа. Несущим объявляется счётный: дефект-класс, +ломающийся в 20–30% глав при ~0 у компаратора, разрешается уже на 25–30 единицах. + +Прибор — `eval/dovodka/schet.py`, $0, детерминированный. Четыре класса объявлены ЗДЕСЬ и до снятия: + +| класс | что считается | +|---|---| +| **род** | форма 1 л. ед. ч. прош. вр. с неверным родом. Три подкласса, не пересекаются: **«эталон»** — пол голоса внутреннего рассказа по окну установлен, форма ему противоречит; **«разнобой»** — пол по окну НЕ устанавливается, а арм ставит в одном слое ОБА рода (дефект внутренний, исходника для него не требуется; дефектом считается МЕНЬШИНСТВО форм); **«речь»** — род, не принадлежащий ни одному объявленному цитируемому говорящему | +| **язык** | латиница в русском выходе, КРОМЕ объявленных эталоном иноязычных вставок и римских цифр | +| **приём** | авторский типографский приём исходника (разрядка `P A T I E N C E`), потерянный выходом | +| **банк** | термины банка, чья канонная форма в выходе встречается реже, чем в исходнике (`canon_gaps`) | + +⚠ **Класс «приём» применим к ОДНОЙ главе из шестнадцати** (`197f98eb61`, `P A T I E N C E`) — это +анекдот, а не класс, и он объявляется описательным ДО того, как будет посчитан. + +**⛔ Отбор форм 1 л. ужесточён после проверки исполнением, и первая редакция была негодной.** Она +брала любую форму на `-л/-ла` с местоимением «я» в окне ±40 знаков — и считала третьи лица +(«Габриэль пожал плечами») и СУЩЕСТВИТЕЛЬНЫЕ на `-л` («Пьющий пепел»). На главе `f2274720c9` она +давала 2ж/5м там, где настоящих форм три и все мужские. **Предварительный сигнал «D0 3/1 · E6 3/2 · +RG 0/5», записанный в план 22.08, снят этим ригом и потому НЕ ЯВЛЯЕТСЯ показанием** — он +воспроизводится только негодной редакцией счётчика. В пакеты читателей он не идёт (запрет плана), +и в выводы тоже не идёт. + +Починка: местоимение обязано стоять в синтаксической связи — сразу перед глаголом (через 0–3 +служебных слова) или сразу после него. Правило разделения «повествование / прямая речь» — +механическое и объявлено здесь: абзац-реплика начинается с тире, речь идёт до первого закрывающего +тире перед словами автора, всё после него — повествование. + +### Д32.4а ⛔ ЭТАЛОН СНЯТ ПО ИСХОДНИКУ И СЛЕПО К ПЕРЕВОДАМ + +Требование п.3а плана: «эталон грепов фиксируется ДО снятия, иначе их можно подогнать под +увиденное». Исполнено буквально. Каждую из 16 глав читали **три независимых агента** — строитель +и два скептика, одному из которых выдан мандат ОПРОВЕРГНУТЬ вывод. Каждому был открыт **ровно один +файл**: английский исходник его главы. Русские переводы, код зоны, отчёт и `~/books` были закрыты +запретом в промте. + +**⚠⚠ ПЕРВЫЙ КРУГ ЭТАЛОНА ОКАЗАЛСЯ НЕГОДЕН, И ПОЙМАЛА ЭТО ЕГО ЖЕ СВЕРКА.** Вопрос был задан про +«пол рассказчика», а книга **рамочная**: хронист Jean-François пишет третьим лицом, а рассказ +героя идёт от первого лица внутри кавычек, часто без закрывающей. Половина строителей сочла +внутренний рассказ «прямой речью» и объявила первое лицо отсутствующим — **на восьми главах из +шестнадцати**; скептики это сняли на четырёх, а на остальных согласились с ошибкой. Круг +переспрошен с НАЗВАННОЙ рамкой. Переводы агентам оставались закрыты в обоих кругах — то есть +исправлена ПОСТАНОВКА ВОПРОСА, а не подогнан ответ; оба круга лежат в `eval/dovodka/etalon-panel0.json` +целиком, расхождение видно построчно. + +⚠ **Девиация, которую надо назвать вслух.** Строя счётчик, я до фриза эталона видел выход армов на +нескольких главах — иначе нельзя было поймать, что первая редакция отбора форм считает +существительные. Это увиденное повлияло на ПРИБОР (регекс ужесточён) и не могло повлиять на +ЭТАЛОН: эталон снят агентами, которым выход был закрыт. Считаю девиацию объявленной и не +компенсируемой иначе. + +⚠ **Расход агент-сессий.** Построение эталона стоило 48 сессий в первом круге и 48 во втором. В +журнале `runs.py` они НЕ записаны: журнал держит судейские и читательские сессии, привязанные к +токенам панелей, а эти агенты не судят ничего и токенов не держат. Число называю здесь, чтобы оно +не пропало: при капе 200 и израсходованных 98 читательских это отдельная статья, и её учёт — +вопрос владельцу, а не решение сессии. + +### Д32.5 ПРАВИЛО РЕШЕНИЯ, ОБЪЯВЛЕННОЕ ДО ЧИСЕЛ + +* **Первичная величина — число ГЛАВ С ≥1 ФАТАЛОМ** любого из четырёх классов (агрегат). +* **Тест — парный знаковый по главам, `p < 0.05`.** Реализация одна на зону (`zsud._sign_p`), + второй не заводится. +* По-классовые разбивки — **вторичные**, печатаются рядом и вердикта не несут. +* Ранги слепого чтения — **описательные**, объявлено выше. +* Вердикт формулируется как **«интеракция архитектура × жилец на ИСПЫТАННЫХ жильцах»**, НЕ как + «минимакс»: худший редактор не искался, связка двухвендорна (черновик — DeepSeek). + +### Д32.6 СВЕРКИ ДО ЧТЕНИЯ + +1. **Исходник у всех армов побайтно один — и это доказано построением, а не сличением.** + `uid = sha1(source.strip())[:10]` (`bakeoff.uid_of`), а совпадающий uid у клетки `E6` и клетки + `RG` есть на всех 16 главах. Разный исходник дал бы разный uid. +2. **Потолки вывода напечатаны** — таблица Д32.1, асимметрия названа в Д32.3. +3. **Промт `E6` распечатан `--wire`-аналогом и прочитан.** Аналог собран **кодом его собственного + рига** (`en_axis`: исходник, черновик `D0`, `PR.editor_msgs` пары en, тело вызова строит + РОСТЕР НАПРЯМУЮ), а не пере-написан в `rol.py`, — иначе гейт показывал бы, что я думаю о + клетке, а не что ушло в модель. Прочитано вслух: промт **пар-корректен** (несёт «МЕРЫ + английской традиции… НЕ пересчитывай в метрические», «КАЛЬКИ en→ru», французский слой) — + блокера Б1 здесь нет; глоссарий доехал (`Dior → «Диор»`, `Reyne → «Рейн»`, `Celene → «Селена»` + и ещё пять). ⚠ И ровно на этом промте видно то, что Шаг 7 плана называет второй половиной мины: + **в глоссарии есть имена и нет ни одного поля пола** — «Рейн» приезжает к модели как строка, + без указания, он это или она. +4. `--verify-read` обязан вернуть **EXIT=0**; ключ пишется ДО ответов; раскладка своя на каждую + главу; один читатель на главу. + +### Д32.7 ⛔ ТРИ ДЕФЕКТА НАШЛИСЬ В САМОМ ПРИБОРЕ, И НАШЛИ ИХ ГЛАЗА, А НЕ ГЕЙТ + +Порядок работы был такой: блокер сборки снят → эталон снят агентами вслепую → классы и правило +решения объявлены → счётчик прогнан → **улики прочитаны глазами по каждому попаданию** → найдены +три дефекта прибора → починены → счётчик прогнан заново. Печатаю оба свода, чтобы читатель судил +сам: правка, сделанная ПОСЛЕ первых чисел, обязана предъявлять и старые числа. + +1. **Правило слоёв не знало ВОЗОБНОВЛЕНИЯ реплики.** Русская вёрстка диалога чередуется: + «— речь, — слова автора. — речь». Первая редакция обрывала речь на первом тире и всё дальнейшее + звала повествованием. Цена замерена: на главе `49ca859c94` реплика Жан-Франсуа «…как и я, + мадемуазель Кастия. Нет, я сбежал в Огюстен…» ложилась в ПОВЕСТВОВАНИЕ, и мужская форма + мужского говорящего шла в дефекты рассказчицы — **у всех трёх армов сразу**. Прибор производил + брак вместо того, чтобы его находить. +2. **Речь проверялась даже там, где пол голоса не установлен.** На `5a8f48d24a` собственная + реплика рассказчицы «— Где я была?» уходила в дефекты как «род ж не принадлежит ни одному + говорящему главы»: в списке говорящих стоят только Персиваль и Вульфрик (оба «м»), а сама + рассказчица в него не входит по определению. Теперь неустановленный пол голоса выключает + проверку речи целиком. +3. **Класс «язык» был слеп к латинице В РАЗРЯДКУ.** Регекс требовал двух букв подряд, а + `P A T I E N C E` — восемь одиночных через пробел. Поймано чтением: **`RG` единственный + сохранил авторскую разрядку главы `197f98eb61` — и сохранил её ПО-АНГЛИЙСКИ.** Свод хвалил бы + арм за непереведённое слово. ⚠ И это снимает предварительный сигнал плана «разрядку потерял сам + черновик → потеряли и `E6`, и `RG`»: разрядку сохранил `ZF` (кириллицей, верно) и `RG` + (латиницей, не переведя), потеряли `ZD`, `Z0` и `E6`. + +Каждая починка закрыта ФАЛЬСИФИКАЦИЕЙ в селфтесте (подсаженный брак обязан ловиться, чистый текст +обязан давать ноль), и правки двигали числа в ОБЕ стороны: первая убрала дефекты у всех армов, +третья добавила один арму `RG`. + +**⛔ И ЧЕТВЁРТАЯ НАХОДКА — НЕ В ПРИБОРЕ, А В ДВИЖКЕ ЗАМЕРА: ЛАТЕНТНАЯ МИНА ДВУХ КОНТУРОВ ВЫСТРЕЛИЛА.** +Селфтест `rol.py` с 22.08 печатал предупреждение: в процессе живут ДВА экземпляра `contour`, и +`wire()` настраивал только один — второй оставался на китайской паре; тогда было записано «до +данных не добралось». 23.08 добралось. Скрипт, честно позвавший `PAIRS["en"]["wire"]()` и сразу +спросивший текст БЕСПЛАТНОГО арма, получил **пустую строку**: `free_text` идёт в контур ЗАХОДА, тот +искал китайскую клетку английской главы, не нашёл и вернул пусто с одним `warning`. В своде это +читалось бы как «у арма на этой главе мало дефектов» — пустой текст дефектов не имеет по построению. +Починено в корне: пара включается в ОБОИХ экземплярах одной командой (`rol._wire`), проверка +селфтеста оставлена сторожем на случай третьего экземпляра. Дополнительно счётчик **выбрасывает из +счёта главу с пустым текстом хоть у одного арма и печатает это вслух** — арм с пропавшей клеткой +не имеет права выглядеть лучшим. + +### Д32.8 ⭐ РЕЗУЛЬТАТ СЧЁТНОГО ПРИБОРА + +**Попаданий (не глав), 16 глав, четыре класса. Слева — до починок прибора, справа — после.** + +| класс | ZD | Z0 | ZF | RG | E6 | +|---|---|---|---|---|---| +| **род** | 2 → **0** | 2 → **0** | 2 → **0** | 8 → **5** | 4 → **1** | +| **язык** | 2 → **2** | 0 → **0** | 0 → **0** | 8 → **9** | 0 → **0** | +| **приём** | 1 → **1** | 1 → **1** | 0 → **0** | 0 → **0** | 1 → **1** | +| **банк** | 25 → **25** | 9 → **9** | 7 → **7** | 10 → **10** | 9 → **9** | +| **фаталов всего** | 30 → **28** | 12 → **10** | 9 → **7** | 26 → **24** | 14 → **11** | +| **глав с ≥1 фаталом** | 13 → **13** | 10 → **8** | 8 → **6** | 11 → **12** | 10 → **8** | + +**Частота глав с дефектом и 95% интервал Уилсона** (требование плана §4: по редким классам печатать +частоту с интервалом, а не вердикт): + +| класс | ZD | Z0 | ZF | RG | E6 | +|---|---|---|---|---|---| +| род | 0/16 [0.00;0.19] | 0/16 [0.00;0.19] | 0/16 [0.00;0.19] | **2/16** [0.03;0.36] | 1/16 [0.01;0.28] | +| язык | 2/16 [0.03;0.36] | 0/16 [0.00;0.19] | 0/16 [0.00;0.19] | **4/16** [0.10;0.49] | 0/16 [0.00;0.19] | +| приём | 1/16 | 1/16 | 0/16 | 0/16 | 1/16 | +| банк | 12/16 [0.51;0.90] | 7/16 [0.23;0.67] | 6/16 [0.18;0.61] | 7/16 [0.23;0.67] | 7/16 [0.23;0.67] | +| **все** | 13/16 [0.57;0.93] | 8/16 [0.28;0.72] | 6/16 [0.18;0.61] | 12/16 [0.51;0.90] | 8/16 [0.28;0.72] | + +**Парный знаковый тест. ① — правило, объявленное планом (бинарно «глава с ≥1 фаталом»); +② — вторичное, число фаталов на главу.** + +| контраст | ① бинарно | ② счётно | +|---|---|---| +| `Z0 − E6` (**один промт, разные жильцы**) | 0 глав различия, p=1.0000 | −1, 1 глава, p=1.0000 | +| `RG − E6` (**один жилец, разные топологии**) | +4, 4 главы, **все за `E6`**, p=0.1250 | +13, 6 глав, **все за `E6`**, **p=0.0312 РАЗЛИЧИМО** | +| `Z0 − RG` | −4, 4 главы, все за `Z0`, p=0.1250 | −14, 6 глав, все за `Z0`, **p=0.0312 РАЗЛИЧИМО** | +| `ZF − RG` | −6, 6 глав, все за `ZF`, **p=0.0312 РАЗЛИЧИМО** | −17, 8 глав, все за `ZF`, **p=0.0078 РАЗЛИЧИМО** | +| `ZD − Z0` | +5, 5 глав, все за `Z0`, p=0.0625 | +18, 10 глав, все за `Z0`, **p=0.0020 РАЗЛИЧИМО** | +| `ZD − E6` | +5, 5 глав, все за `E6`, p=0.0625 | +17, 9 глав, все за `E6`, **p=0.0039 РАЗЛИЧИМО** | +| `ZD − RG` | +1, 5 глав, 3 за `RG`, p=1.0000 | +4, 11 глав, 7 за `RG`, p=0.5488 | + +⚠ **ПОТОЛОК МОЩНОСТИ, ПЕЧАТАЕТСЯ РЯДОМ С КАЖДЫМ «НЕ РАЗЛИЧИМО».** При всех расхождениях в одну +сторону двусторонний знаковый p = 2/2^k, то есть **p<0.05 недостижим, пока глав с ненулевой +разницей меньше шести**. Классы «род» (2 главы) и «язык» (4 главы) эта панель не разрешит НИКОГДА, +как бы односторонен ни был результат. «Не различимо» здесь означает «прибор слеп», а не «армы +одинаковы» — и по построению, а не по невезению. + +### Д32.9 ⭐⭐ ЧТО ЭТО ЗНАЧИТ — И ЧЕГО НЕ ЗНАЧИТ + +**Читается это так.** Возьмите один и тот же слабый жилец `glm-5` с погашенным размышлением. + +* Поставьте его **редактором** над боевым черновиком (`E6`) — он даёт **8 глав из 16 с браком, + 1 попадание по роду, 0 по языку**. Боевой `deepseek-v4-pro` в той же топологии, с тем же + побайтно промтом (`Z0`) — **8 из 16, 0 и 0**. Между ними **НОЛЬ глав различия** по первичному + правилу и −1 фатал по вторичному. То есть по классу А смена жильца внутри архитектуры прибором + НЕ ловится. +* Поставьте того же жильца **однопроходкой** (`RG`) — **12 глав из 16, 5 попаданий по роду, + 9 по языку**. Против `E6` разница в 6 главах, **все шесть в одну сторону**, p=0.0312 по + вторичному правилу; против второй генерации связки `ZF` — 6 глав, все в одну сторону, p=0.0312 + **по ПЕРВИЧНОМУ**. + +⇒ **Буфер существует и замерен.** Топология «дорогой чужой черновик → слабый жилец редактором» +снимает у слабого жильца 4 из 5 дефектов рода и все 9 дефектов языка по сравнению с тем же +жильцом, делающим работу в одиночку. + +⛔⛔ **И ЧЕГО ЭТО НЕ ЗНАЧИТ — ПЯТЬ ОГОВОРОК, КАЖДАЯ СНИМАЕТ ЧАСТЬ ВЫВОДА.** + +1. **Первичное правило контраст `RG−E6` НЕ ЗАКРЫВАЕТ** (p=0.1250). Закрывает вторичное и закрывает + `ZF−RG`. По конъюнкции, которой фаза меряет вендоров, это «направление единогласно, значимость + не достигнута». Печатать «однопроходка различимо хуже редактора» нельзя; печатать «различимо + хуже второй генерации связки» — можно. +2. **Это интеракция «архитектура × жилец на ИСПЫТАННЫХ жильцах», а не минимакс.** Худший редактор + не искался. `glm-5` — не «худший вендор», а единственный второй, которого мы пробовали в этой + роли. +3. **Буфер ДВУХВЕНДОРЕН.** Черновик делает `deepseek-v4-flash`. Архитектура, которая «спасает + слабого жильца», сама содержит клетку другого вендора — и на неё же опирается. Утверждение + «наша архитектура вендоро-независима» этим замером НЕ проверено. +4. **Буфер чинит только то, что черновик донёс, и это видно прямо здесь.** Разрядку + `P A T I E N C E` черновик `ZD` потерял → потерял и `E6`. Уцелела она у `ZF` (вторая генерация + связки, кириллицей) и у `RG` (латиницей, не переведя). Контракт «что обязан гарантировать + черновик» — не украшение, а условие работы буфера. +5. **Конфаундер объёма промта играет ЗА однопроходку** (×1.80), значит её проигрыш — вывод + более сильный, чем объявленный, а не более слабый. Это единственная оговорка, работающая в + пользу вывода, и потому её мало. + +**Отдельно — то, чего никто не заказывал, а замер отдал бесплатно.** Черновик `deepseek-v4-flash` +за $0.00055 за клетку дал **0 дефектов рода на всех 16 главах** — там, где `glm-5` однопроходкой за +впятеро большие деньги дал 5. Дешёвая модель в узкой роли не уступила дорогой в широкой. +⚠ Но она же дала **25 потерь банка против 9–10 у всех прочих** и 2 непереведённых английских слова: +черновик хорош ровно там, где его страхуют. + +### Д32.10 ⭐⭐ НАХОДКА ПОД ВОПРОС 0, ПОЛУЧЕННАЯ ЗА $0 + +Эталон, снятый по исходнику вслепую, дал побочный результат, которого никто не искал, и он бьёт +прямо в метавопрос владельца. + +**В 2 окнах из 8, где есть рассказчик от первого лица, его пол ПО ОКНУ НЕ УСТАНАВЛИВАЕТСЯ вовсе.** +Голос главы `5a8f48d24a` — Селена (цепочка «обращение по имени → немедленное „Где я была?“» +замыкается жёстко), но во всём окне нет ни одного `she` о ней; голос `c3517980c7` — Гейб, и точно +так же ни одного `he`. Это установлено ТРЕМЯ независимыми чтениями каждой главы, причём двоим из +трёх был выдан мандат опровергнуть. + +⇒ **Пайплайн, который видит только главу, по построению слеп примерно в четверти случаев.** Он не +«ошибается» — ему нечем узнать. Узнать может ТОЛЬКО книжная память: тот же голос (Селена) ведёт +ещё три окна нашей выборки, и там пол устанавливается прямо. То же у Габриэля: 3 окна из 4. + +⛔ **А в банке полей пола НЕТ.** `bank-en.json` несёт имена и канонные формы — «Рейн», «Селена», +«Диор» — и ни одного поля рода; это видно на распечатке промта `E6` (Д32.6 п.3). То есть +механизм, который единственный мог бы закрыть эти 25% глав, в наших прогонах **не существовал**. + +⇒ Это первое ПРЯМОЕ и бесплатное подтверждение тезиса Шага 7 плана: «решение „банк чинит пол“ не +имеет ни одного замера», и «пол плывёт у всех» его не опровергает — механизма просто не было. +Теперь известно и сколько он стоил бы: без него ~25% первололичных глав неразрешимы в принципе. + +⚠ Оценка 2 из 8 снята на маленькой выборке: интервал Уилсона [0.07; 0.59]. Число — порядок +величины, не константа. diff --git a/eval/dovodka/etalon-panel0.json b/eval/dovodka/etalon-panel0.json new file mode 100644 index 00000000..61307f3e --- /dev/null +++ b/eval/dovodka/etalon-panel0.json @@ -0,0 +1,1139 @@ +{ + "001e6ac4eb": { + "род_голоса": "ж", + "голос": "Celene", + "определим_по_окну": true, + "уверенность": "high", + "улики_голоса": [ + "I met those black eyes, fervor flooding into my cold, Dead chest.", + "He’d seemed a kindly soul as he listened to my tale, gentle thoughts bidding me speak", + "May I have this one? I have never taken communion with one born of Voss. I would be honored to carry her to—", + "Your turn ? You lack-witted clot-bucket, it was I who found her—", + "A wand’ring lamb hath found her shepherd, and we shall not scorn divine providence. Celene abides with us now. I will show her the footsteps our Founder gave us." + ], + "говорящие": [ + { + "имя": "Aleks", + "род": "ж", + "улика": "«My turn! Aleks thumped her breast.» — прямое her в повествовании рассказчицы; её реплика с 1 л. прош.: «it was I who found her—»." + }, + { + "имя": "Percival", + "род": null, + "улика": "«the little one named Percival watching with knife-bright eyes» — ни одного местоимения о самом Персивале в этом окне; her в «I would be honored to carry her» относится к рассказчице, не к говорящему. Имя конвенционально мужское, но по условию догадка по имени уликой не считается." + } + ], + "иноязычные_вставки_агентов": [ + "Esana" + ], + "латиница_законна": [], + "приёмы_агентов": [ + { + "вид": "капс целым словом", + "текст": "ENOUGH" + } + ], + "приёмы": [], + "клаузы_повествования": [ + "I met those black eyes", + "I’d been raised godly", + "the same fire I’d once felt in our chapel back in Lorson", + "It was a prayer he spoke, I realized", + "a chill uncoiled in my belly as I saw a terrible wrath in him unveiled", + "I realized it was not through love that this strange pair were bound to his service" + ], + "клаузы_речи": [ + { + "english": "I have never taken communion with one born of Voss", + "speaker": "Percival", + "gender": "unknown" + }, + { + "english": "I would be honored to carry her to—", + "speaker": "Percival", + "gender": "unknown" + }, + { + "english": "it was I who found her—", + "speaker": "Aleks", + "gender": "female" + } + ], + "слои": "Внешней рамки (3 л., хронист) в этом окне нет вовсе: каждый абзац открыт непарными “‘ — всё окно целиком есть ВНУТРЕННИЙ РАССКАЗ, записанный со слов героини. Внутренний слой — повествование от 1 л. в прошедшем («I met those black eyes», «I realized», «I’d been raised godly»): рассказчица только что обращена, слушает молитву Вульфрика и наблюдает свару двух вампиров о ней самой. Третий слой — цитируемые ею реплики внутри рассказа: молитва и приказы Вульфрика («The Vow, we call it», «ENOUGH», «God hath given us a gift this night»), просьба Персиваля («May I have this one?») и грызня Алекс («it was I who found her—», «My turn!»); род в них принадлежит цитируемому говорящему, не рассказчице.", + "заметки": "Цепочка на женский род замыкается внутри окна и без опоры на имя: рассказчица присутствует при сцене («I met those black eyes… my cold, Dead chest»), это ей Вульфрик внимал («as he listened to my tale»), и именно о ней спорят вампиры — «this one», «one born of Voss», «I would be honored to carry her», «it was I who found her»; Вульфрик закрывает спор, назвав найденную по имени: «Celene abides with us now. I will show her…». Отсюда voice_name = Celene, род женский.\n\nЧто НЕ вошло в narration_clauses: «And evil I do» (наст. вр.) и «lest evil I be» (исключено условием) — это к тому же строки цитируемой молитвы Вульфрика, а не рассказ; «The Vow, we call it» и «we call it» (наст. вр., мн. ч.); «he told me», «he declared», «Wulfric looked up», «He’d seemed a kindly soul» (3 л., род на «я» не ложится); «I will show her» и «we shall not scorn» (будущее). У Вульфрика в этом окне нет ни одной клаузы «я + прошедшее», поэтому в quoted_speakers он не внесён, хотя его пол в окне установлен прямо («he told me», «his face», «he stood now»).\n\nЛовушка перевода: «I’d been raised godly» — пассив; по-русски род всё равно всплывает при естественном «я росла набожной / меня растили набожной» — переводчику придётся выбрать форму, и род будет помечен.\n\nАрхаика молитвы (hath, ye, wand’ring, «A wand’ring lamb hath found her shepherd») — регистровый приём, а не типографский, поэтому в typographic_devices не внесена; кавычки-«ёлочки»/непарные “‘ тоже не приём, а разметка слоя. Разрядки буквами в окне нет.\n\nforeign_inserts: французского в этом окне нет ни слова; «Esana» в «The Vow Esana» — иноязычный литургический термин, обязанный остаться чужим (не переводить как «Обет Эсаны» в смысле кальки — сохранять как имя обряда). «Voss» и «Lorson» — топонимы/родовые имена, транслитерируются, к иноязычным вставкам не отношу.", + "адъюдикация": "", + "круг2_сверка": [ + { + "согласен": true, + "свой": "ж", + "имя": "Celene", + "улика": "Весь отрывок — внутренний рассказ (каждый абзац открыт «‘), рамки 3-го лица в окне нет. Рассказчик — 1 л., прош. вр.: «I met those black eyes, fervor flooding into my cold, Dead chest. I'd been raised godly… the same fire I'd once felt in our chapel back in Lorson». Цепочка на «я»: (1) рассказчик — та, кто только что изложила свою историю: «He'd seemed a kindly soul as he listened to my tale, gentle thoughts bidding me speak»; (2) о ней же в цитируемом диалоге Персиваль просит у мастера, женским местоимением: «May I have this one? … I would be honored to carry her to—»; (3) Алекс спорит о той ", + "возражения": [] + }, + { + "согласен": true, + "свой": "ж", + "имя": "Celene", + "улика": "Окно целиком — внутренний рассказ (каждый абзац открыт “‘), рамки в нём нет. Пол рассказчицы устанавливается ТОЛЬКО через три упоминания её третьими лицами в цитируемых репликах: Персиваль — «May I have this one? I have never taken communion with one born of Voss. I would be honored to carry HER to—» и «it was I who found HER—»; Вульфрик — «A wand'ring lamb hath found HER shepherd, and we shall not scorn divine providence. Celene abides with us now. I will show HER the footsteps our Founder gave us.» Цепочка замыкается на рассказчицу, а не на постороннего: спор идёт о «this one» / «one born of", + "возражения": [ + "Две из пяти заявленных улик о рассказчице род вообще не несут. «I met those black eyes, fervor flooding into my cold, Dead chest» — голое 1 л. без родового маркера (это клауза, ТРЕБУЮЩАЯ выбора рода, а не дающая его). «He'd seemed a kindly soul as he listened to my tale, gentle thoughts bidding me speak» — улика о ВУЛЬФРИКЕ (он мужчина), поданная как улика о рассказчице: ровно тот тип подмены, что велено ловить. Вердикт держится исключительно на трёх «her» в чужих репликах — их и следовало приводить.", + "Пропущен целый цитируемый говорящий: ВУЛЬФРИК. Внутри рассказа он говорит трижды — «The Vow, we call it… The Vow Esana», «ENOUGH», «God hath given us a gift this night… Celene abides with us now. I will show her the footsteps our Founder gave us». Пол его прямо задан повествованием («he told me», «he declared», «his service», «He'd seemed a kindly soul»), male. В списке цитируемых говорящих его нет.", + "Не атрибутированы две начальные стихотворные строки «And evil I do, lest evil I be, / No more than the monster ye made me» — по контексту («It was a prayer he spoke, I realized») это хвост молитвы Вульфрика, то есть цитируемая речь, а не повествование. Рода они, впрочем, не метят («ye made me» — подлежащее ye).", + "Список «клауз повествования, обязанных пометить род» непоследователен по охвату. Если он про род РАССКАЗЧИЦЫ — тогда улика №2 («He'd seemed a kindly soul…») в него противоречиво не входит, а в улики попала. Если про род вообще — пропущены клаузы повествования, метящие род ДРУГИХ: «Noooo, Aleks growled» (прорычала) и «My turn! Aleks thumped her breast» (ударила) — единственные места, где вообще проявляется женский род Aleks; плюс «Wulfric looked up», «he told me», «he declared», «But he stood now», «Wulfric's voice snapped… both vampires fell silent».", + "Пол Percival назван unknown верно, но не отмечено, что это ВЫНУЖДЕННАЯ дыра: его собственные реплики содержат три клаузы, которые в русском обязаны выбрать род — «I have never taken communion» (принимал/принимала), «I would be honored to carry her» (был бы удостоен/была бы удостоена / почёл/почла за честь), «it was I who found her» (нашёл/нашла). То есть переводчик обязан бросить монету там, где окно ответа не даёт; это следовало вынести явно, а не оставить как нейтральный unknown.", + "Женский род Aleks выведен из единственного местоимения в «Aleks thumped her breast», и держится на идиоматическом чтении «ударила себя в грудь» (her = своя). Чтение принимаю, но это одна опора без дубля, а не подтверждённая цепочка — стоило пометить как ниже уверенностью, чем female у рассказчицы." + ] + } + ], + "круг1_сырой": { + "род": "female", + "первое_лицо": true, + "сверка": [ + { + "согласен": true, + "свой": "ж" + }, + { + "согласен": true, + "свой": "ж" + } + ] + } + }, + "100b088f71": { + "род_голоса": null, + "голос": "неизвестно", + "определим_по_окну": false, + "уверенность": "high", + "улики_голоса": [], + "говорящие": [], + "иноязычные_вставки_агентов": [ + "ancien", + "château" + ], + "латиница_законна": [], + "приёмы_агентов": [], + "приёмы": [], + "клаузы_повествования": [], + "клаузы_речи": [], + "слои": "Внутреннего рассказа от первого лица здесь нет вовсе. Всё окно — справочный/энциклопедический слой третьим лицом (dramatis personae, статьи-персоналии: «Maryn —…», «Jènoah —…», «Wulfric —…»), написанный тем же внешним голосом, что и рамка: «She was murdered…», «He was master of a grim keep…», «Wulfric had naught to do with Gabriel's upbringing». Цитируемая речь ровно одна — предсмертная надпись Jènoah кровью на полу часовни: «This wait too long. This weight too heavy. Father, forgive me.»; она безглагольна плюс императив, первого лица в прошедшем времени в ней нет. Таким образом: рамка/справка = 3 л., внутренний рассказ = отсутствует, цитируемая реплика = одна, без родомечущих форм.", + "заметки": "В окне нет ни одного I/me/my/we во внутреннем слое: единственное «me» — в императиве цитаты «Father, forgive me» (Jènoah, мужчина), а императив в русском род не метит («отец, прости меня»), поэтому в dialogue_clauses он не идёт. Род в переводе метить всё же придётся, но по ТРЕТЬЕМУ лицу и по явным he/she самого текста, а не по голосу: «She was murdered» / «She was entombed» / «She bears» (Maryn — she, «The Mother of Monsters», «the eldest surviving member»); «He was master of a grim keep» / «the ancien had taken his own life» (Jènoah — he); «Wulfric had naught to do…» / «he returned briefly» (Wulfric — he, «Gabriel's father»); «he was lover to Gabriel's mother, Auriél», «when she fell pregnant» (Auriél — she); «After her Becoming, Celene tracked Wulfric» (Celene — she). Эти клаузы схемой не запрашиваются (не первое лицо), но переводчику они обязательны — фиксирую, чтобы не выглядело, будто родомечущих мест в отрывке нет совсем. Французское держать чужим: «ancien» (термин-титул, не «древний») и «château»; топонимы и имена (Charbourg, Fabién Voss, Dún Maergenn, Cairnhaem, León, San Yves, Auriél, Jènoah) — обычная передача, к иноязычным вставкам не отношу. Разрядки и капса как приёма в окне нет; кавычки вокруг предсмертной надписи — обычная прямая речь, не типографский приём в смысле схемы.", + "адъюдикация": "", + "круг2_сверка": [ + { + "согласен": true, + "свой": null, + "имя": "неизвестно", + "улика": "Отрывок целиком — не повествование, а справочный аппарат (dramatis personae / глоссарий): подряд идут словарные статьи «Maryn —The Mother of Monsters…», «Jènoah —One of the four surviving Esani…», «Wulfric —Gabriel’s father, and warrior of the Esani line…». Всё изложено третьим лицом и с внешней, энциклопедической точки зрения: «She was murdered during a cataclysmic battle…», «He was master of a grim keep named Cairnhaem…», «Little is known of him, save he dwelled for a time in León». Ни одного абзаца, открытого непарной “ или ‘ и ведущего рассказ от первого лица в прошедшем времени, в окне не", + "возражения": [] + }, + { + "согласен": true, + "свой": null, + "имя": "неизвестно", + "улика": "Окно (1671 знак, один абзац) целиком — приложение/dramatis personae внешнего слоя, третьим лицом и без рассказчикова «я». Пытался снять вывод тремя способами, все три не сработали.\n\n1) Поиск первого лица по всему файлу даёт РОВНО одно вхождение — «me» в «Father, forgive me.», и оно внутри кавычек предсмертной записи Jènoah. Ни одного I/my/we/our больше нет. Значит внутреннего рассказа от 1 л. в этом окне нет вообще — снимать нечего.\n\n2) Типографский признак внутреннего рассказа (абзац открывается НЕПАРНОЙ “ или ‘) отсутствует. В файле одна пара кавычек, и она ПАРНАЯ и ЗАКРЫТАЯ: «...upon the fl", + "возражения": [ + "Неблокирующая неточность в списке «цитируемые говорящие — []»: формально в окне ЕСТЬ один цитируемый говорящий — Jènoah, чьи написанные кровью слова приведены в кавычках («This wait too long. This weight too heavy. Father, forgive me.»). На вердикт это не влияет по двум причинам: цитата принадлежит внешнему справочному слою, а не внутреннему рассказу (которого в окне нет), и ни одна её форма в русском рода не метит — «This wait too long»/«This weight too heavy» безглагольно-именные, «Father, forgive me» — императив. Пол самого Jènoah при этом задан не цитатой, а третьеличным «He was master of a grim keep»." + ] + } + ], + "круг1_сырой": { + "род": "not_applicable", + "первое_лицо": false, + "сверка": [ + { + "согласен": true, + "свой": null + }, + { + "согласен": true, + "свой": null + } + ] + } + }, + "197f98eb61": { + "род_голоса": "м", + "голос": "Gabriel (силверсейнт, «the silversaint»)", + "определим_по_окну": true, + "уверенность": "high", + "улики_голоса": [ + "“I had more important things to fret on.” The silversaint tipped his head back, draining his wine in one long gulp. “We’d reached San Maximille.”", + "Reaching out slow, he filled his goblet slower. And from his bones, he sighed.", + "“This prophecy may be the greatest riddle of our age, Gabriel.” The historian’s eyes narrowed to knifecuts.", + "Jean-François found himself staring too; those scars and beautiful tattoos. A wreath of skulls atop his right hand, roses upon his left" + ], + "говорящие": [], + "иноязычные_вставки_агентов": [ + "Jean-François", + "château", + "Fabién", + "San Maximille", + "Augustin" + ], + "латиница_законна": [], + "приёмы_агентов": [ + { + "вид": "разрядка буквами через пробел", + "текст": "P A T I E N C E" + } + ], + "приёмы": [ + { + "вид": "разрядка", + "текст": "P A T I E N C" + } + ], + "клаузы_повествования": [ + "I had more important things to fret on", + "I was sure the château would be abandoned", + "I couldn’t quite fathom it" + ], + "клаузы_речи": [], + "слои": "РАМКА (3 л.): хронист смотрит на шрамы и татуировки собеседника — «Jean-François found himself staring too», «The historian's eyes narrowed to knifecuts», «The silversaint tipped his head back… he filled his goblet slower… he sighed»; в рамке же звучит вопрос хрониста «This prophecy may be the greatest riddle of our age, Gabriel.» / «How in the name of God could it not matter?». ВНУТРЕННИЙ РАССКАЗ (1 л., прош. вр., в непарных кавычках) — ответ и повествование серебряного святого Габриэля: «I had more important things to fret on», «We'd reached San Maximille», далее абзацы про марш после освобождения поезда, зиму, Ranger Valley, разведку у San Maximille и застывшего в укреплениях врага. ЦИТИРУЕМЫХ реплик других персонажей внутри рассказа в этом окне нет — Lachie только упомянут, не говорит.", + "заметки": "Цепочка замыкается двумя звеньями сразу: (1) реплику от первого лица «I had more important things to fret on» / «We'd reached San Maximille» атрибутирует речевой тег «The silversaint tipped HIS head back… HE sighed», то есть говорящий — мужчина; (2) хронист обращается к этому же собеседнику по имени: «…the greatest riddle of our age, Gabriel». Дальше без смены говорящего идёт внутренний рассказ («I was sure the château…»), значит род глаголов — мужской.\n\nЧто НЕ вошло в narration_clauses и почему: все «we»-клаузы («We’d reached San Maximille», «We’d marched as hard as we could», «the prisoners we’d saved», «we’d no choice», «they’d slowed our pace», «our scouts returned», «by the time we drew close enough») — в русском 1 л. МН. ч. прош. вр., род там не метится. Туда же «Lachie and I were already drawing up plans to meet Fabién in the field»: по-русски это «мы с Лахи уже составляли планы» — множественное, рода нет; клауза формально с «I», но 1 л. ед. ч. не даёт.\n\n«I had more important things to fret on» звучит в рамочном разговоре (ответ хронисту), а не внутри воспоминания, но это тот же голос, и естественный русский оборот («я тревожился о более важном» / «мне было о чём тревожиться помимо этого») род метит — поэтому оставлен в narration_clauses, а не вынесен отдельно.\n\nГендерно-нейтральные ловушки перевода: «I couldn’t quite fathom it» → «я не мог(ла) взять в толк» — род обязателен; «I was sure» → «я был уверен» — обязателен. Обойти их безличной конструкцией можно, но это уже потеря, а не решение.\n\nТипографика: разрядка «P A T I E N C E» в исходнике разорвана переносом строки (…P A T I E N C / E across his fingers) — это один приём, а не две единицы; в переводе должна остаться разрядкой (например Т Е Р П Е Н И Е), а не курсивом или капсом. Капса целым словом как приёма в окне нет; «years .» — просто артефакт пробела перед точкой.\n\nФранцузское: «château» — нарицательное, обязано остаться чужим (шато/château), не «замок». Имена Jean-François, Fabién, Augustin и топоним San Maximille сохраняют диакритику и чужую форму. «Lachie», «Ranger Valley», «Shield of Augustin», «silversaint» — не французские, в список не внесены (хотя «silversaint» — авторский термин и требует книжного канона, а не разового перевода).", + "адъюдикация": "", + "круг2_сверка": [ + { + "согласен": true, + "свой": "м", + "имя": "Gabriel (the silversaint)", + "улика": "Frame is 3rd person around Jean-François the historian; the inner story is 1st person past. Chain: (1) the historian addresses his interlocutor by name — \"“This prophecy may be the greatest riddle of our age, Gabriel.” The historian’s eyes narrowed to knifecuts.\"; (2) the answer to that is tagged to the silversaint — \"“I had more important things to fret on.” The silversaint tipped his head back, draining his wine in one long gulp. “We’d reached San Maximille.”\" — so Gabriel = the silversaint = the speaker; (3) that same speaker carries the first-person narration: \"I was sure the château would", + "возражения": [] + }, + { + "согласен": true, + "свой": "м", + "имя": "Gabriel (силверсейнт, «the silversaint»)", + "улика": "Слои в окне: рамка 3 л. («Jean-François found himself staring too…», «The historian’s eyes narrowed to knifecuts») и внутренний рассказ 1 л. в кавычках, начинающийся с «We’d marched as hard as we could after liberating that meat train…». Владелец внутреннего «я» назван рамочной атрибуцией прямо перед рассказом и помечен мужским родом трижды: «The silversaint tipped his head back, draining his wine in one long gulp», «Reaching out slow, he filled his goblet slower. And from his bones, he sighed». Это тег говорящего (не описание третьего лица), и следующий за ним абзац в кавычках — его же расска", + "возражения": [ + "Клауза «I had more important things to fret on» попала в список «обязанных пометить род» зря по ДВУМ причинам. (а) Слой: это не внутреннее повествование, а реплика Габриэля в РАМОЧНОМ диалоге — прямой ответ на вопрос хрониста «How in the name of God could it not matter?»; внутренний рассказ начинается только со следующего абзаца («We’d marched as hard as we could…»). (б) Даже как реплика она в русском рода НЕ метит: естественные переводы безличны/посессивны — «у меня были заботы поважнее», «мне хватало забот поважнее», «было о чём тревожиться и без того». Ни одной согласуемой по роду формы. На вывод это не влияет (говорящий тот же), но как «клауза повествования, обязанная пометить род» она ложная.", + "Улика №4 («Jean-François found himself staring too… A wreath of skulls atop his right hand, roses upon his left») внутри окна двусмысленна по референту: «his» грамматически может быть отнесено и к самому Jean-François. Как улика о ПОЛЕ РАССКАЗЧИКА она нерабочая и держится только на том, что оба кандидата мужчины. Рабочие улики — теги при самой реплике рассказчика («The silversaint tipped his head back», «he filled his goblet», «he sighed»), их и надо предъявлять; описание татуировок — украшение, а не звено цепи.", + "Список «цитируемые говорящие — []» верен только при строгом чтении «цитируемые ВНУТРИ внутреннего рассказа» (там прямой речи действительно нет). Но в окне есть второй говорящий прямой речью — хронист Jean-François («This prophecy may be the greatest riddle of our age, Gabriel», «How in the name of God could it not matter?»), мужчина по рамке. Если поле означает «прочие говорящие окна», пустой список — пропуск.", + "Отождествление силверсейнта с именем Gabriel в этом окне не доказано текстуально, а выведено из хода диалога (обращение к Gabriel → ответ от «The silversaint»); «found himself staring too» вообще намекает, что в сцене есть кто-то третий, кто тоже смотрел. Вывод о ПОЛЕ от этого не страдает (он идёт от «his/he» при теге рассказчика), но имя голоса стоит держать как «силверсейнт, по обращению — Gabriel», а не как установленный факт." + ] + } + ], + "круг1_сырой": { + "род": "not_applicable", + "первое_лицо": false, + "сверка": [ + { + "согласен": false, + "свой": "м" + }, + { + "согласен": true, + "свой": null + } + ] + } + }, + "26c3bff1d4": { + "род_голоса": "м", + "голос": "Gabriel de León (Габриэль де Леон), Последний сребросвятой", + "определим_по_окну": true, + "уверенность": "high", + "улики_голоса": [ + "“BELLS RINGING, BOOTS pounding, heart thundering, I ran.” Gabriel drank from his goblet, wincing at the souring taste.", + "His face had taken on a familiar, faraway expression, as if he stared into memory and distance both.", + "“Out from the château,” Gabriel said, “across the plaza, toward the Tower of Tears.", + "The Last Silversaint held out his goblet.", + "Jean-François could hear the silversaint’s pulse quickening now, as it often did when he began recounting tales of his battles." + ], + "говорящие": [], + "иноязычные_вставки_агентов": [ + "Rive Nord", + "Rive Cœur", + "River Béni", + "château", + "capitaines" + ], + "латиница_законна": [], + "приёмы_агентов": [ + { + "вид": "caps", + "текст": "BELLS RINGING, BOOTS" + }, + { + "вид": "caps", + "текст": "TO THE FLOOD" + } + ], + "приёмы": [], + "клаузы_повествования": [ + "I ran" + ], + "клаузы_речи": [], + "слои": "Рамка — третьим лицом вокруг хрониста и его собеседника: «The historian looked up from the page he’d thumbed back to, meeting the silversaint’s eyes», «The Last Silversaint held out his goblet. Jean-François poured the bottle’s clotted last into the cup», «Gabriel drank from his goblet, wincing at the souring taste», плюс курсивная мысль хрониста «I will miss this when it’s over». Внутрь рамки вставлены реплики Жана-Франсуа, обращённые ко второму лицу («You’d done all he’d asked, de León… he’d betrayed you»), и цитата-указ «Two days and nights I grant thee». Внутренний рассказ начинается с главы VIII «TO THE FLOOD» и идёт от первого лица в прошедшем: «BELLS RINGING, BOOTS pounding, heart thundering, I ran», продолжаясь безглагольным «Out from the château… across the plaza, toward the Tower of Tears. The square was in uproar…»; цитируемых чужих реплик внутри этого рассказа в окне нет.", + "заметки": "Цепочка замкнута жёстко: реплика с «I ran» стоит вплотную к атрибуции «Gabriel drank from his goblet… His face had taken on…», а следующий абзац того же рассказа прямо помечен «Gabriel said»; тот же персонаж в рамке — «the silversaint» / «The Last Silversaint held out HIS goblet», к нему же обращается Жан-Франсуа: «You’d done all he’d asked, de León». Пол голоса — мужской, «я побежал».\n\nЕдинственная финитная клауза внутреннего рассказа в окне — «I ran»; всё остальное во внутреннем слое либо безглагольные обстоятельственные обрывки-продолжения («Out from the château, across the plaza, toward the Tower of Tears»), либо третьелицые описания («The square was in uproar», «bells pealing on cold streets»). Обрывок «Out from the château…» — синтаксическое продолжение «I ran»; если переводчик подставит туда глагол, он ОБЯЗАН быть мужского рода («бросился/бежал»), поэтому смотреть за ним стоит, но самостоятельной клаузой я его не считаю.\n\nЧто намеренно НЕ включено: «Two days and nights I grant thee» — цитируемый указ Вечного Короля, настоящее время, род не метит; «I will miss this when it’s over. And it will be over soon.» — курсивная мысль Жана-Франсуа, слой РАМКИ и будущее время, к голосу внутреннего рассказа отношения не имеет.\n\nДополнительно (вне запрошенных полей, но перевод там тоже пометит род): реплики Жана-Франсуа во втором лице к Габриэлю — «You’d done all he’d asked», «just as you knew he must» — по-русски дадут «ты сделал / ты знал», мужской род; а «he’d camped», «he’d betrayed you», «he himself couldn’t snuff out», «your brother á Craeg had promised» — мужской род третьего лица (Вечный Король, á Craeg).\n\nИмена «de León», «á Craeg», «Jean-François» — не французские лексические вставки, а онимы; в foreign_inserts не вынесены, но транслитерируются, а не переводятся. «Rive Nord» / «Rive Cœur» — топонимы-обороты, которые обязаны остаться французскими (не «Северный берег»).", + "адъюдикация": "", + "круг2_сверка": [ + { + "согласен": true, + "свой": "м", + "имя": "Gabriel de León (Габриэль де Леон), Последний сребросвятой", + "улика": "Внутренний рассказ начинается с главы VIII: «“BELLS RINGING, BOOTS pounding, heart thundering, I ran.”» — и тут же атрибутируется рамкой: «Gabriel drank from his goblet, wincing at the souring taste.» Продолжение того же рассказа прямо помечено говорящим: «“Out from the château,” Gabriel said, “across the plaza, toward the Tower of Tears.» Значит «я», которое бежало, — Gabriel. Он же отождествлён с адресатом рамки: хронист обращается «You’d done all he’d asked, de León», а рядом «The Last Silversaint held out his goblet» и «meeting the silversaint’s eyes» — Gabriel = de León = Последний сребро", + "возражения": [] + }, + { + "согласен": true, + "свой": "м", + "имя": "Gabriel de León (Габриэль де Леон), Последний сребросвятой", + "улика": "Слои: рамка — 3 л. (Jean-François читает страницу, обращается «de León»; «The Last Silversaint held out his goblet. Jean-François poured…»); после разрыва главы «VIII / TO THE FLOOD» — внутренний рассказ в непарных кавычках от 1 л. прош. вр.: «BELLS RINGING, BOOTS pounding, heart thundering, I ran.» Цепочка личности замыкается: адресуемый «de León» = «The Last Silversaint» (та же сцена, протягивает кубок) = «Gabriel», причём тег стоит ВНУТРИ самой цитаты повествования: «“Out from the château,” Gabriel said, “across the plaza, toward the Tower of Tears.» Пол — не по имени, а по трём независимым", + "возражения": [ + "Сам внутренний рассказ в этом окне не содержит ни одного маркера пола: «I ran», «Out from the château…», «The square was in uproar…» — все нейтральны. Пол держится целиком на местоимениях РАМКИ («his goblet», «His face», «his battles»). Улика #1 процитирована единым блоком, где маркер («his goblet») лежит в рамочном теге, а не в цитате; формулировка это смазывает. Вывод не падает — тег «Gabriel said» стоит внутри самой цитаты повествования и жёстко сшивает слои, — но основание надо называть точно.", + "Улика #5 («as it often did when he began recounting tales of his battles») местоименно двусмысленна сама по себе: в предложении два мужских участника, и «he» разрешается только семантикой «his battles» + «the silversaint’s pulse». Как самостоятельная улика слабая, лишь дублирует #2/#4.", + "Улика #2 («His face had taken on…») опирается на антецедент из предыдущего предложения, а не на явное имя; вырванная из контекста читается как возможная отсылка к хронисту. Внутри окна разрешается верно, но её следовало приводить в связке с предшествующим «Gabriel drank from his goblet».", + "Список цитируемых говорящих пуст, но в окне есть чужая прямая речь — «“ Two days and nights I grant thee. ”» (слова Forever King, зачитанные хронистом). Она лежит в рамочном слое и в русском рода не метит (настоящее время), поэтому на замер не влияет; строго корректная формулировка — «цитируемых говорящих нет ВНУТРИ внутреннего рассказа», а не «в окне».", + "Неатрибутированные реплики «The song of warning bells.» и открывающий абзац про песню повисают без говорящего: окно выдрано из середины, опираться на них нельзя. Маркеров рода в них нет, так что на вывод это не влияет." + ] + } + ], + "круг1_сырой": { + "род": "male", + "первое_лицо": true, + "сверка": [ + { + "согласен": true, + "свой": "м" + }, + { + "согласен": true, + "свой": "м" + } + ] + } + }, + "27cb3a7e69": { + "род_голоса": null, + "голос": "неизвестно", + "определим_по_окну": false, + "уверенность": "high", + "улики_голоса": [], + "говорящие": [], + "иноязычные_вставки_агентов": [ + "capitaine", + "Capitaine" + ], + "латиница_законна": [], + "приёмы_агентов": [], + "приёмы": [], + "клаузы_повествования": [], + "клаузы_речи": [], + "слои": "Внешней рамки (3 л. про хрониста) в этом окне нет вовсе: каждый абзац открывается непарной “ — всё окно целиком есть ВНУТРЕННИЙ РАССКАЗ, который герой диктует хронисту. Голос этого рассказа говорит о себе только во множественном числе — «we could not read her thoughts», «the Grail's mind was a locked room to us», «we followed», «we could feel their turmoil»; всё остальное повествование о Диор, Фиби, Хоакине и Безвольных идёт третьим лицом. Внутри рассказа есть свой цитируемый диалог (одинарные ‘ ’): реплики Диор («Let's go see your brother», «Open it», «Open the cunting door, Capitaine»), ответная реплика собеседника («No, Dior. Reyne was not your sister.») и обрывок капитана («My Lady Grail—»).", + "заметки": "Ключевое: первое лицо во внутреннем рассказе есть, но оно СПЛОШЬ МНОЖЕСТВЕННОЕ — we/us и ни одного I/me/my. Русское прошедшее время во мн. ч. род не метит («мы не могли прочесть её мысли», «мы пошли следом», «мы чувствовали их смятение»), поэтому в этом окне перевод НЕ вынужден пометить род нигде — ни в повествовании, ни в репликах. Отсюда пустые narration_clauses и dialogue_clauses: это не пропуск, а свойство окна.\n\nВсе места первого лица (для контроля, что ничего не потеряно): «We could not read her thoughts», «the Grail's mind was a locked room to us», «she looked to us and spat», «sharing a glance with the duskdancer, we followed», «we could feel their turmoil». По окну не определить, «мы» — это несколько человек (рассказчик + Фиби, поскольку Хоакин и Безвольные названы отдельно: «Joaquin and the Unbound hurrying in the Grail's wake») или единый рассказчик, говорящий о себе во мн. ч. Обе трактовки дают в русском одинаковую бесполую форму; единственный риск — если переводчик самовольно свернёт «we» в «я», он будет вынужден выдумать род, которого в тексте нет.\n\nПол персонажей окна известен, но к голосу отношения не имеет: Диор — женщина («She hung her head», «her fury», «My Lady Grail»), капитан — мужчина («a heavyset fellow», «The man looked to his fellows»), Фиби — «the duskdancer», род по окну не задан. Ни одна цитируемая реплика не содержит «я + прошедшее время»: у Диор только императивы и настоящее («Let's go», «Open it», «Open the cunting door»), у собеседника — третье лицо («Reyne was not your sister»), у капитана — оборванное обращение. Поэтому quoted_speakers пуст.\n\nРазрядки буквами через пробел и капса целым словом в окне нет. Из иноязычного обязателен к сохранению чужим только «capitaine» / «Capitaine» — и как существительное («Their capitaine was a heavyset fellow»), и как обращение в реплике Диор; «Augustin» — топоним и передаётся транслитерацией, поэтому в список не внесён.", + "адъюдикация": "", + "круг2_сверка": [ + { + "согласен": true, + "свой": null, + "имя": "неизвестно", + "улика": "Внутренний рассказ (весь текст в открывающих кавычках, прошедшее время) ведётся от первого лица МНОЖЕСТВЕННОГО числа и рассказчик ни разу не назван: «We could not read her thoughts—as always, the Grail's mind was a locked room to us», «a blindworm could have seen her fury as she looked to us and spat», «sharing a glance with the duskdancer, we followed», «None among the Unbound spoke, but we could feel their turmoil». Ни одного гендерного маркера, приложенного к этому «мы», в окне нет. Все названные лица от голоса отделены: Dior — «she», Грааль, объект наблюдения («Dior demanded», «she stalked", + "возражения": [ + "Вердикт верен, но список улик пуст, а улика здесь ЕСТЬ и она положительная: голос не «не определяется из-за нехватки текста», а прямо и последовательно говорит о себе во множественном числе — «We could not read her thoughts», «the Grail's mind was a locked room to us», «she looked to us and spat», «we could feel their turmoil». Это надо было зафиксировать: рассказчик — безымянное «мы», а не молчащий/неопознанный «я».", + "Не зафиксировано следствие для замера: при рассказчике-«мы» русское прошедшее время рода не несёт («мы не могли», «мы последовали»), то есть в этом окне пол голоса недоступен не только по уликам, но и структурно — переводу его неоткуда взять и негде проявить.", + "Не показано, что кандидаты отсеяны: в окне есть Dior (she), Phoebe/duskdancer (she), Joaquin, capitaine («a heavyset fellow… thick moustache») — и каждый текстом отделён от «мы» («sharing a glance with the duskdancer, we followed», «we followed, Joaquin and the Unbound hurrying in the Grail's wake»). Без этого «unknown» выглядит как отказ от разбора, хотя разбор возможен и даёт тот же ответ." + ] + }, + { + "согласен": true, + "свой": null, + "имя": "неизвестно", + "улика": "Всё окно — внутренний рассказ (каждый абзац открывается непарной “/‘, клауз внешней рамки нет). Рассказчик говорит от 1 л. МНОЖЕСТВЕННОГО числа: «We could not read her thoughts—as always, the Grail's mind was a locked room to us», «she looked to us and spat», «sharing a glance with the duskdancer, we followed», «we could feel their turmoil». В русском прошедшее мн. ч. («не могли», «последовали», «чувствовали») род не метит вообще, поэтому клауз повествования, обязанных пометить род рассказчика, в окне НЕТ — структурно, а не по случайности. Все родомечающие прошедшие формы окна относятся к трет", + "возражения": [ + "Список цитируемых говорящих [] неверен по факту окна: во внутреннем рассказе звучат минимум три голоса — Диор («‘Let’s go see your brother.’» сразу после «she looked to us and spat»; «‘Open it,’ Dior demanded»; «‘Open the cunting door, Capitaine.’»), капитан («‘My Lady Grail—’», описан как «a heavyset fellow with a scarred chin and thick moustache» → м.р.) и неатрибутированный говорящий реплики «‘No, Dior. Reyne was not your sister.’». Род Диор в окне УСТАНОВЛЕН (she/her/«My Lady Grail» → ж.р.), и пустой список это стирает.", + "Уточнение к тому же пункту (ограничение, не переворот): ни одна из этих реплик не требует родомечающей формы говорящего — императивы («Open it», «Open the cunting door»), побудительное «Let’s go», назывное обращение «My Lady Grail». Единственная прошедшая форма в цитируемой речи — «She wasn’t…» / «Reyne was not your sister» — метит род РЕЙН (третьего лица), а не говорящего. Поэтому на вердикт по рассказчику неполнота списка не влияет.", + "«улики []» — занижение. Позитивная улика о характере голоса в окне есть и она решающая: рассказчик — «мы» (We/us, четыре вхождения). Из неё следует, что unknown получен не из бедности окна, а из того, что русское мн. ч. род не метит в принципе; для замера это разные вещи, и вторую надо было записать.", + "Проверка на пропущенную клаузу дала ноль: в окне нет ни одной прошедшей формы с подлежащим «я»/«мы» рассказчика, кроме плюральных «could not read», «followed», «could feel» — в переводе все идут во мн. ч. и рода не метят.", + "Проверка на подмену слоя дала ноль в обе стороны: реплики Диор и капитана никем не записаны в повествование, а повествовательные «we followed» / «we could feel» никем не записаны в реплики. Ловушка «догадка по имени» тоже не сработала — имени рассказчика окно не содержит вовсе." + ] + } + ], + "круг1_сырой": { + "род": "unknown", + "первое_лицо": true, + "сверка": [ + { + "согласен": true, + "свой": null + }, + { + "согласен": true, + "свой": null + } + ] + } + }, + "3bd6481182": { + "род_голоса": "м", + "голос": "неизвестно", + "определим_по_окну": true, + "уверенность": "high", + "улики_голоса": [ + "“‘Packing your things. You’re gone from here today.’ “‘Bull shit…’ “‘He speaks truth, Joaquin,’ Aaron said.", + "saw his eyes on the bags I was loading", + "‘This isn’t about Dior anymore,’ I growled.", + "That thought sobered Joaquin and me both. Aaron was just as hungry as I, remember.", + "“‘He caught me by surprise, Capitaine. N-next time, I’ll be ready.’" + ], + "говорящие": [], + "иноязычные_вставки_агентов": [ + "Capitaine" + ], + "латиница_законна": [], + "приёмы_агентов": [], + "приёмы": [], + "клаузы_повествования": [ + "'This isn't about Dior anymore,' I growled", + "I walked to Joaquin's side", + "I turned back to his horse to spare him the shame of his tears", + "I couldn't blame him a drop, in truth", + "I turned at Joaquin's whisper", + "saw his eyes on the bags I was loading", + "the bags I was loading", + "I smiled weakly" + ], + "клаузы_речи": [ + { + "english": "I've tried, boy.", + "speaker": "рассказчик (тот, кого зовут «Capitaine»)", + "gender": "male" + }, + { + "english": "God help me, I've tried to keep this thing in me chained.", + "speaker": "рассказчик (тот, кого зовут «Capitaine»)", + "gender": "male" + } + ], + "слои": "Внешней рамки (3 л., хронист) в этом окне НЕТ ни одной фразы: каждый абзац открывается непарной “ — это сплошной ВНУТРЕННИЙ РАССКАЗ от 1 л. прошедшего времени (герой рассказывает хронисту сцену прощания с Жоакином в пещере). Внутри рассказа идёт СВОЙ диалог в одинарных ‘…’: реплики Жоакина (заикание d-doing, n-not, m-me), Аарона и самого рассказчика; атрибуции при них («he whispered», «Aaron said», «I growled») принадлежат внутреннему рассказу, а не рамке. Персонажей в сцене ровно трое: рассказчик, Жоакин, Аарон.", + "заметки": "Цепочка на пол голоса замкнута внутри окна и не опирается на имя. (1) Пакует вещи и грузит сумки именно рассказчик: «saw his eyes on the bags I was loading», «I walked to Joaquin's side», «I turned back to his horse» — значит реплика «Packing your things. You're gone from here today.» принадлежит ему. (2) На неё Жоакин отвечает «Bull shit…», и Аарон подтверждает: «He speaks truth, Joaquin». «He» тут не может быть ни Аароном (говорит о себе он бы «I»), ни Жоакином (к нему обращаются по имени и на «you»), а в сцене ровно трое — «That thought sobered Joaquin and me both. Aaron was just as hungry as I» — следовательно «He» = рассказчик. Отсюда male. Обращение «Capitaine» (Жоакин) поддерживает вывод, но само по себе слабее: формально оно может адресоваться и Аарону, чья реплика предшествует.\n\nИмени рассказчика в окне нет: названы Joaquin, Aaron, Dior; к рассказчику обращаются только «Capitaine».\n\nЧто сознательно НЕ вошло в narration_clauses: «That thought sobered Joaquin and me both» (рассказчик — объект, рода в русском не метит); «Aaron was just as hungry as I» (в русском «как и я» без связки); «squeezing his shoulder» (деепричастие, род не метит); «We wrapped the lad in furs, turned him east, and watched him trudge away» и «Aaron and I answering with the same» — 1 л. МНОЖЕСТВЕННОГО числа, русское прошедшее мн. ч. рода не метит; «I'll not be able to stop it», «I'll save Dior», «I vow», «I swear it» — будущее/настоящее.\n\nДополнительный род-маркер вне рамок схемы (2 л., не 1 л.): «You've done enough, son» и «I've tried, boy» / «You ride out with us now» — в русском «ты сделал достаточно» пометит род ЖОАКИНА (мужской, он же «son», «boy», «the lad»).\n\nТипографика: «Someone will have to stop me .» — пробел перед точкой почти наверняка след курсивного выделения слова «me» в оригинале; курсив в typographic_devices по условию не идёт, разрядки буквами и капса целым словом в окне нет.", + "адъюдикация": "", + "круг2_сверка": [ + { + "согласен": true, + "свой": "м", + "имя": "неизвестно", + "улика": "Внутренний рассказ ведёт «я», который пакует вещи Joaquin и выгоняет его: «Packing your things. You’re gone from here today.» — что подтверждается позже его же словами «I turned at Joaquin’s whisper, saw his eyes on the bags I was loading». Рассказчик НЕ Aaron и НЕ Joaquin: «That thought sobered Joaquin and me both. Aaron was just as hungry as I, remember» (обращение «remember» — к хронисту рамки). Замыкающая улика на род: сразу после реплики рассказчика «Packing your things…» идёт «‘He speaks truth, Joaquin,’ Aaron said» — говорит Aaron, адресат Joaquin, значит «He» может указывать только на ", + "возражения": [ + "Вывод (male) верный, но список улик наполовину нерабочий: решает только одна фраза — «‘He speaks truth, Joaquin,’ Aaron said», где Aaron говорит о рассказчике в третьем лице мужского рода. У другого читателя она утоплена внутрь длинной первой цитаты и не выделена как замыкающая; связка «реплика ‘Packing your things…’ принадлежит рассказчику» (доказывается через «saw his eyes on the bags I was loading») не проговорена, а без неё «He» повисает.", + "«saw his eyes on the bags I was loading» — улика на то, ЧТО делает рассказчик (грузит сумки), и на то, что «his» = Joaquin; про пол самого рассказчика она не говорит ничего.", + "«‘This isn’t about Dior anymore,’ I growled» — чистая атрибуция реплики рассказчику, рода в ней нет (в русском переводе как раз это место и требует уже установленного рода, а не даёт его).", + "«That thought sobered Joaquin and me both. Aaron was just as hungry as I, remember» — отделяет рассказчика от Aaron и Joaquin (полезно для идентификации голоса), но пол не устанавливает.", + "«‘He caught me by surprise, Capitaine. N-next time, I’ll be ready.’» — это реплика Joaquin (его заикание: «d-doing», «t-too much», «w-we have»), а не рассказчика; «He» здесь — третий, напавший, а не рассказчик. Обращение «Capitaine» — воинский титул, во французском форма мужская независимо от пола носителя, так что уликой на пол он не является; догадка по титулу того же сорта, что догадка по типу имени." + ] + }, + { + "согласен": true, + "свой": "м", + "имя": "unknown", + "улика": "Голос внутреннего рассказа — мужской, доказано ОДНОЙ уликой в окне: цепочкой «‘Packing your things. You’re gone from here today.’ (реплика рассказчика) → ‘Bull shit…’ (Жоакин) → ‘He speaks truth, Joaquin,’ Aaron said. ‘You can’t stay here. Not anymore.’». Аарон обращается к Жоакину, значит «He» — третье лицо; единственный предыдущий говорящий — рассказчик, и продолжение Аарона («You can’t stay here») подтверждает ровно сказанное рассказчиком. Что паковал вещи именно рассказчик, подтверждено повествованием: «saw his eyes on the bags I was loading». Что рассказчик ≠ Аарон — «Aaron was just as hu", + "возражения": [ + "Вывод (male + имя неизвестно) верен, но список улик наполовину непробативен: реально доказывает пол ровно один фрагмент — «‘He speaks truth, Joaquin,’ Aaron said», где Аарон называет рассказчика «he». В приведённой цитате он есть, но не выделен, и по составу списка неясно, что именно доказывает вывод.", + "Улика «That thought sobered Joaquin and me both. Aaron was just as hungry as I, remember.» — улика о ДРУГОМ персонаже, не о рассказчике. «Was hungry» относится к Аарону; в русском «Аарон был так же голоден, как и я» окончание рода несёт Аарон, эллипсис «как и я» рода не метит, а «sobered ... me» ставит рассказчика в винительный падеж. Пола рассказчика этот фрагмент не устанавливает вовсе.", + "Улика «‘He caught me by surprise, Capitaine. N-next time, I’ll be ready.’» — это реплика ЖОАКИНА о третьем лице («he» = напавший) плюс обращение по титулу. Пола рассказчика она не даёт: «Capitaine»/«капитан» рода носителя не метит, а «I’ll be ready» — это род Жоакина, а не рассказчика.", + "Улики «‘This isn’t about Dior anymore,’ I growled» и «saw his eyes on the bags I was loading» перепутаны с уликами о поле: это клаузы, ТРЕБУЮЩИЕ рода в русском, но сами по себе род не задающие. Они уже стоят в списке клауз; в списке улик они создают ложное впечатление независимых подтверждений.", + "Список цитируемых говорящих пуст — это фактическая ошибка и ровно та путаница слоёв, о которой предупреждает задание. В окне два цитируемых говорящих помимо рассказчика: Joaquin (‘What are you d-doing?’ he whispered / ‘Bull shit…’ / ‘He caught me by surprise, Capitaine. N-next time, I’ll be ready.’ / ‘That’s t-too much.’) и Aaron (‘He speaks truth, Joaquin,’ Aaron said). Цена ошибки не косметическая: именно реплика Аарона — единственный источник вывода о поле, а реплика Жоакина «N-next time, I’ll be ready» в русском требует рода («буду готов/готова»), и его мужской род подтверждён повествованием («the boy», «son», «lad», «He hung his head»).", + "В списке клауз «the bags I was loading» вложена в уже перечисленную «saw his eyes on the bags I was loading» — это одно и то же место предложения, посчитанное дважды; как отдельная клауза оно завышает число точек замера.", + "Клауза «‘This isn’t about Dior anymore,’ I growled» приписана слою целиком вместе с репликой: род метит только повествовательный тег «I growled» («прорычал я»), содержимое кавычек рода не несёт. Границу клаузы стоит резать по тегу, иначе слои смешаны.", + "Пропущены места, где род рассказчика метится в его СОБСТВЕННЫХ репликах: «I’ve tried, boy. God help me, I’ve tried to keep this thing in me chained» → «я пытался/пыталась», дважды. По правилу слоёв это не повествование, но это тот же голос; если список клауз используется как чек-лист замера, эти две точки выпадают из проверки." + ] + } + ], + "круг1_сырой": { + "род": "male", + "первое_лицо": true, + "сверка": [ + { + "согласен": true, + "свой": "м" + }, + { + "согласен": true, + "свой": "м" + } + ] + } + }, + "49ca859c94": { + "род_голоса": "ж", + "голос": "Celene (Celene Castia, «The Last Liathe»)", + "определим_по_окну": true, + "уверенность": "high", + "улики_голоса": [ + "Celene shook her head. “I am told in years before daysdeath, horses were so common that a farmer might afford one to plow his fields.", + "Horses feared me now, but I had always been fascinated with them", + "“You were a peasant boy, Marquis?” Jean-François looked across the river, eyes narrowed. The Last Liathe was watching him, expressionless, cold as the stone she sat upon.", + "“My lady finds as little joy in the rustic charms of the provinces as I did, M lle Castia." + ], + "говорящие": [ + { + "имя": "Jean-François", + "род": "м", + "улика": "“A farmer’s son, oui. We lived near San Maximille. … No, I ran away to Augustin to seek my fortune.” — пол закреплён рамкой и обращением: «The historian frowned, staring into the dark as he realized», «He smiled softly», «“You were a peasant boy, Marquis?”»" + } + ], + "иноязычные_вставки_агентов": [ + "château", + "Rive Cœur", + "oui", + "M lle", + "Rive Nord", + "artiste" + ], + "латиница_законна": [ + "oui" + ], + "приёмы_агентов": [], + "приёмы": [], + "клаузы_повествования": [ + "I had always been fascinated with them", + "I found myself smiling in soft wonder", + "I had never seen so many beautiful beasts in my life" + ], + "клаузы_речи": [ + { + "english": "I ran away to Augustin to seek my fortune", + "speaker": "Jean-François", + "gender": "male" + }, + { + "english": "Apprenticed with an artiste of some repute", + "speaker": "Jean-François", + "gender": "male" + }, + { + "english": "Rented a squalid little loft in Rive Nord with a handful of other starving dreamers", + "speaker": "Jean-François", + "gender": "male" + }, + { + "english": "Painted portraits and fucked the occasional fatcat to make the rent", + "speaker": "Jean-François", + "gender": "male" + }, + { + "english": "My lady finds as little joy in the rustic charms of the provinces as I did", + "speaker": "Jean-François", + "gender": "male" + } + ], + "слои": "Рамка — 3 л.: хронист Jean-François слушает у реки («Celene shook her head», «Jean-François looked across the river, eyes narrowed», «The historian frowned», «He smiled softly»). Внутренний рассказ — то, что в кавычках говорит Celene: конец описания смотра войск («The finest were the last to muster… cavaliers from the château at Daggercoast») и абзац о лошадях от 1 л. прош. вр. («Horses feared me now, but I had always been fascinated with them… I found myself smiling…»). Цитируемых реплик ВНУТРИ её рассказа нет; зато в рамке идёт живой диалог, где Jean-François рассказывает о себе от 1 л. прош. вр. («I ran away to Augustin», «Rented a squalid little loft») — это слой реплик, а не внутреннего рассказа.", + "заметки": "Цепочка замыкается внутри окна: абзац с «I had always been fascinated» открыт ремаркой «Celene shook her head»; следующая реплика («You were a peasant boy, Marquis?») принадлежит ей же, и рамка тут же называет её «The Last Liathe … cold as the stone she sat upon» (she), а Jean-François обращается к ней «M lle Castia» (мадемуазель). Итого рассказчица — женщина, догадка по имени не требуется.\n\nНамеренно НЕ включены в narration_clauses: «I am told» (наст. вр.), «Horses feared me now» (подлежащее — лошади, мн. ч., род не метится), «watching those cavaliers parade…» (деепричастие «глядя»), «The finest were the last to muster» (3 л.).\n\nНамеренно НЕ включены в dialogue_clauses: «We had three», «We lived near San Maximille» (1 л. МН. ч. — «у нас было», «мы жили», род не метится), «I can’t remember the third one» (наст. вр.), «The wolf frets not for the ills of the worm» (наст. вр., афоризм). «My dark mother was one of my subjects» метит род МАТЕРИ («была»), а не говорящего, поэтому в список 1 л. не идёт.\n\nПограничный пункт: «as little joy … as I did» — эллипсис; род вылезет только если переводчик развернёт его в глагол («как когда-то находил их я»), при варианте «как и мне когда-то» род не метится. Включил, потому что естественный русский разворот всё же глагольный.\n\nПервая строка отрывка («The finest were the last to muster…») — хвост той же речи в кавычках, но первого лица в ней нет, так что на определение пола она не влияет.\n\nРазрядки буквами через пробел и капса целым словом в окне нет; «M lle Castia» — это осыпавшийся надстрочник Mᴸᴸᴱ (Mademoiselle), типографский артефакт исходника, а не приём: по-русски это обращение «мадемуазель Кастия» либо сохранённое Mlle.", + "адъюдикация": "", + "круг2_сверка": [ + { + "согласен": true, + "свой": "ж", + "имя": "Celene Castia (the Last Liathe)", + "улика": "1) Action beat between two quoted segments identifies the teller: \"...from the château at Daggercoast.” Celene shook her head. “I am told in years before daysdeath, horses were so common that a farmer might afford one to plow his fields.\" 2) The inner narration is first person past: \"Horses feared me now, but I had always been fascinated with them, and watching those cavaliers parade through the streets of Rive Cœur, I found myself smiling in soft wonder. I had never seen so many beautiful beasts in my life.\" 3) The narrator's question back to the chronicler is immediately followed by the fram", + "возражения": [] + }, + { + "согласен": true, + "свой": "ж", + "имя": "Celene (Celene Castia, «The Last Liathe»)", + "улика": "Голос внутреннего рассказа — Celene, женский, и это устанавливается ПРЯМО в окне, без цепочек: рамочная атрибуция, обрамляющая блок повествования, — «Celene shook HER head.» Далее без смены говорящего идёт первое лицо: «I am told… Horses feared me now, but I had always been fascinated with them… I found myself smiling in soft wonder. I had never seen so many beautiful beasts in my life.» Независимый второй маршрут к тому же результату: участников в сцене двое; вопросы «You were a peasant boy, Marquis?» и «Your Empress found you there?» задаёт НЕ Jean-François (он на них отвечает: «A farmer's s", + "возражения": [ + "Мелкая ошибка слоя (на вывод не влияет): Jean-François отнесён к «цитируемым говорящим ВНУТРИ рассказа», но его реплики принадлежат РАМКЕ — это диалог хрониста с рассказчицей, а не речь, которую Celene цитирует внутри своей истории. Внутри повествования Celene в этом окне цитируемых реплик нет вообще. Пол его при этом определён верно и по рамочным уликам.", + "Формулировка «обязаны пометить род» завышена для двух клауз из трёх: «I had always been fascinated with them» и «I found myself smiling in soft wonder» по-русски штатно уходят в безличное («меня всегда завораживали лошади», «на губах сама собой появилась улыбка») и тогда род НЕ метят. Жёстко обязательна только «I had never seen so many beautiful beasts in my life» → «я никогда не видела». Для замера список верен (если переводчик берёт 1sg прошедшего, он обязан быть женским), но как «обязательные» три клаузы засчитывать нельзя — иначе перевод-обход будет ошибочно помечен как провал.", + "Отмечаю как не-возражение, чтобы не выдать за улику: сама по себе связка Celene = The Last Liathe = Castia в окне текстуально не произнесена и держится на допущении «в сцене двое». Допущение подтверждается структурой диалога, но опираться на него не пришлось — «Celene shook her head» и «M lle Castia» дают female порознь." + ] + } + ], + "круг1_сырой": { + "род": "not_applicable", + "первое_лицо": false, + "сверка": [ + { + "согласен": false, + "свой": "ж" + }, + { + "согласен": false, + "свой": "ж" + } + ] + } + }, + "53f1a12dff": { + "род_голоса": null, + "голос": "неизвестно", + "определим_по_окну": false, + "уверенность": "high", + "улики_голоса": [], + "говорящие": [], + "иноязычные_вставки_агентов": [ + "château" + ], + "латиница_законна": [], + "приёмы_агентов": [], + "приёмы": [], + "клаузы_повествования": [], + "клаузы_речи": [], + "слои": "Всё окно целиком — ВНЕШНЯЯ РАМКА, третьим лицом, с фокализацией на хронисте Jean-François («Jean-François asked», «he could hear», «sending a thrill along Jean-François's skin», «Looking behind him, he found Kariim»). Ни одного абзаца, открытого непарной кавычкой и ведущего рассказ от «я» в прошедшем времени, здесь нет — ВНУТРЕННЕГО РАССКАЗА в этом окне НЕТ ВООБЩЕ. Третий слой присутствует: цитируемые реплики персонажей внутри рамки — Dario («The Lion is returned to his cell, Master…»), Jean-François («What news, love?», «Preparing him for his end, I suppose», «Come… Dress me»), Kariim/the Spider («Oh! Beauty», «What delight… to gaze 'pon thee again»). Это диалог рамки, а не цитаты внутри рассказа героя.", + "заметки": "1) Внутреннего рассказа в окне нет, поэтому narration_clauses пуст, а voice_gender = no_voice: это не «не удалось установить», а «первого лица внутреннего слоя здесь физически нет». Единственные «я»-формы во всём отрывке — в репликах рамки, и все они НЕ прошедшего времени: «I suppose» (наст.), «Will you attend» (буд.), «Dress me» (императив), «What news, love?» (безглагольное). 2) Единственная форма прошедшего от 1 л. в репликах — «as soon as we locked him in» (Dario): это 1 л. МНОЖЕСТВЕННОГО числа, а русское «мы заперли» рода не метит, поэтому в dialogue_clauses не вносится. 3) Пол персонажей рамки установлен твёрдо, но к «голосу внутреннего рассказа» отношения не имеет: Jean-François — мужчина («Jean-François sucked his bottom lip», «he could hear», «past portraits Jean-François had painted»); Kariim, Priori of the Ilon — мужчина («He was newly stepped from a grand bedchamber», «His frockcoat was likewise gold», «the Spider»). 4) Скрытая рода-ловушка для перевода, лежащая ВНЕ запрошенных списков: обращение Kariim'а «Oh! Beauty» адресовано Jean-François, то есть по-русски требует мужского («красавец»), а не «красавица»; тем же образом «love» в «What news, love?» адресовано Dario. 5) «to gaze 'pon thee again» — архаика английская, не французская, в foreign_inserts не идёт; château — единственное французское нарицательное, которое перевод обязан сохранить чужим. Имена (Jean-François, Margot, Dario, Kariim, Sul Adair) в переводе транслитерируются, поэтому иноязычными вставками не считаются. 6) Разрядки буквами через пробел и капса целым словом в окне нет.", + "адъюдикация": "", + "круг2_сверка": [ + { + "согласен": true, + "свой": null, + "имя": "нет внутреннего рассказа", + "улика": "Окно целиком лежит во ВНЕШНЕЙ РАМКЕ, 3 л.: \"faithful Dario awaited\", \"Jean-François asked\", \"Jean-François sucked his bottom lip, thoughtful\", \"The pair made their way through the royal wing, past portraits Jean-François had painted\", \"he could hear soft voices\", \"sending a thrill along Jean-François's skin. Looking behind him, he found Kariim\". Ни одного \"I\" в повествовании. Все кавычки в отрывке — обычные ТЕГИРОВАННЫЕ реплики текущей сцены, а не абзацы внутреннего рассказа: \"What news, love?\" Jean-François asked; \"The Lion is returned to his cell, Master.\"; \"Will you attend, Master?\"; \"Come,", + "возражения": [ + "Возражений по существу нет: вердикт (нет внутреннего рассказа, no_voice) совпадает с моим. Единственная претензия процедурная — пустой список улик: ответ верный, но не обоснован, и по нему нельзя отличить корректный разбор рамки от простого отказа. Ожидал бы явной ссылки на третье лицо рамки ('Jean-François asked', 'he could hear') и на то, что все кавычки здесь — тегированные реплики сцены, а не абзацы внутреннего рассказа." + ] + }, + { + "согласен": true, + "свой": null, + "имя": "unknown", + "улика": "Окно целиком принадлежит ВНЕШНЕЙ РАМКЕ, внутреннего рассказа от 1 л. в нём нет вовсе.\n\n1) Типографский тест на внутренний рассказ провален. В файле ровно 9 открывающих “ и 9 закрывающих ” — все кавычки ПАРНЫЕ, все девять фрагментов короткие и являются репликами диалога: «What news, love?» · «The Lion is returned to his cell, Master…» · «Preparing him for his end, I suppose.» · «Will you attend, Master?» · «Come,» · «Dress me.» · «Oh! Beauty.» · «What delight,» · «to gaze ’pon thee again.». Ни одного абзаца, открывающегося непарной “ или ‘ (признак внутреннего рассказа), нет; текст идёт единым ", + "возражения": [ + "Не опровержение, а определительный риск: список «цитируемые говорящие» пуст ТОЛЬКО при строгом чтении «реплики, цитируемые рассказчиком ВНУТРИ внутреннего рассказа». Если ниже по конвейеру этот список понимается шире — «любой говорящий в окне», — то он не пуст: Dario («The Lion is returned to his cell, Master…»), Jean-François («What news, love?», «Come,», «Dress me.») и Kariim/the Spider («What delight, to gaze ’pon thee again.»). Все трое — рамочные, слоем выше целевого, поэтому на вердикт no_voice это не влияет.", + "Не опровержение, а предупреждение о смежной ошибке: окно НЕ лишено гендерных улик вообще — рамка жёстко метит Jean-François мужским («Jean-François sucked HIS bottom lip», «HE could hear», «Looking behind HIM, HE found Kariim») и Kariim тоже («HIS frockcoat», «broad as heaven» о его плечах). Если замер по ошибке нацелится на рамочный слой вместо внутреннего рассказа, он выдаст male и разойдётся с эталоном; ответ no_voice корректен именно потому, что цель — «я» внутреннего рассказа, а его в окне нет." + ] + } + ], + "круг1_сырой": { + "род": "not_applicable", + "первое_лицо": false, + "сверка": [ + { + "согласен": true, + "свой": null + }, + { + "согласен": true, + "свой": null + } + ] + } + }, + "5a8f48d24a": { + "род_голоса": null, + "голос": "Celene", + "определим_по_окну": false, + "уверенность": "high", + "улики_голоса": [ + "Where were you, Celene?", + "Where was I? My eyes narrowed, sorrow pricked to rage.", + "Percival shook his head, glowering at me.", + "I realized Wulfric was speaking to me, shaking my head as I replied, No. No, Master." + ], + "говорящие": [ + { + "имя": "Percival", + "род": "м", + "улика": "Percival shook his head, glowering at me. … He glanced to Aleks, licking at his lips." + }, + { + "имя": "Wulfric (Master)", + "род": "м", + "улика": "Enough! Wulfric snapped. … He signed the wheel, Aleks moaning in agony as he pressed her blackened knuckles once more to his lips. … He turned to Percival then." + } + ], + "иноязычные_вставки_агентов": [ + "gens d’armes" + ], + "латиница_законна": [], + "приёмы_агентов": [], + "приёмы": [], + "клаузы_повествования": [ + "Where was I?", + "Where I was supposed to be, Percival!", + "I was watching the Whisper!", + "And I saw the fire of fury sparked in those black eyes.", + "still I caught the edge of it", + "I realized Wulfric was speaking to me", + "as I replied", + "I made sure of it" + ], + "клаузы_речи": [ + { + "english": "I told you to tell Master that Aleks and I were headed after our marks!", + "speaker": "Percival", + "gender": "male" + } + ], + "слои": "Внешней рамки (3 л., хронист) в этом окне НЕТ ни одной строки: весь отрывок целиком лежит внутри непарных кавычек “‘, то есть это сплошной ВНУТРЕННИЙ РАССКАЗ от первого лица в прошедшем времени («Percival shook his head, glowering at me», «I realized Wulfric was speaking to me»). Рассказчик — тот, кого Персиваль в кадре зовёт по имени: «Where were you, Celene?» → сразу же «Where was I? My eyes narrowed». Третий слой — ЦИТИРУЕМЫЕ рассказчиком реплики сцены: Персиваль (заикание «m-marks», «t-torches»), Вульфрик-Master (архаика «This be no time», «Were ye followed?», «And thee?») и собственные ответы самого рассказчика, часть которых подана без кавычек, встык к повествованию («as I replied, No. No, Master…»).", + "заметки": "ПОЛ ГОЛОСА ИЗ ЭТОГО ОКНА НЕ УСТАНАВЛИВАЕТСЯ. Цепочка «я = Celene» замыкается жёстко (обращение по имени + немедленное «Where was I?»), а вот цепочка «Celene → он/она» — нет: в отрывке ровно 2 «her» и обе про Aleks («her soul would be lost», «her blackened knuckles»), 4 «his» + «he» — про Персиваля и Вульфрика, «A child. Carrying a full-grown woman through midnight streets?» — реплика Вульфрика о Персивале (ребёнок), несущем Aleks (взрослая женщина), а не о рассказчике. Ни «мадемуазель», ни «сестра/брат», ни местоимения о рассказчике нет; имя Celene уликой не считаю. Женский род у Aleks и мужской у Персиваля/Вульфрика на рассказчика не переносятся.\n\nРазмещение клауз: собственные реплики рассказчика («Where I was supposed to be», «I was watching the Whisper!», «I made sure of it») положены в narration_clauses, а не в dialogue_clauses, потому что род в них — род ГОЛОСА, а не стороннего говорящего; quoted_speakers по условию рассказчика не включает.\n\nПограничные случаи, сознательно НЕ включённые: «I’d no time to run errands for you!» — естественный русский «у меня не было времени» рода не метит (метил бы только натужный «я не имела/не имел»); «we shadowed them», «None saw us», «We have come close to calamity» — 1 л. МН. ч., в прошедшем времени род не метится; «We shall avenge these hurts» — будущее; «If Aleks had died … her soul would be lost» — 3 л. (метит род Aleks, но это не «я»); «My eyes narrowed», «my senses were not as sharp», «shaking my head» — подлежащее не «я», рода рассказчика не дают.\n\nРазрядки и капса в окне нет (проверено grep’ом: ни одного ALLCAPS-слова, ни одной цепочки букв через пробел). Из чужого языка обязателен к сохранению только «gens d’armes»; «Master», «kith», «doves»/«marks» (воровской жаргон), имена Dyvok/Aleks/Wulfric/Percival — не французские вставки. Отдельно для переводчика (не по схеме, но нагружено смыслом): архаика Вульфрика «This be no time», «Were ye followed?», «And thee?» и заикание Персиваля «m-marks»/«t-torches» — маркеры голосов, их нельзя гладко нормализовать. Отрывок обрывается на реплике Вульфрика без закрывающей кавычки — это выдранное окно, а не незакрытая цитата.", + "адъюдикация": "", + "круг2_сверка": [ + { + "согласен": true, + "свой": null, + "имя": "Celene", + "улика": "Narrator identity closes on Celene: \"Percival shook his head, glowering at me.\" (3rd person on Percival, \"me\" = narrator) -> Percival addresses the narrator: \"Where were you, Celene?\" -> narrator answers in her own voice, echoing the question: \"Where was I? My eyes narrowed, sorrow pricked to rage. Where I was supposed to be, Percival! I was watching the Whisper!\" Distinctness confirmed later: \"I realized Wulfric was speaking to me... No. No, Master.\" followed by \"He turned to Percival then. And thee?\" Gender is NOT established in this window: every gendered marker belongs to someone else - Al", + "возражения": [] + }, + { + "согласен": true, + "свой": null, + "имя": "Celene", + "улика": "Voice identity is solid: Percival \"shook his head, glowering at me\" and asks \"Where were you, Celene?\"; the very next paragraph is the narrator's own first person — \"Where was I? My eyes narrowed, sorrow pricked to rage. Where I was supposed to be, Percival! I was watching the Whisper!\" Address + first-person echo closes the chain, so the inner narrator is Celene. Gender is NOT recoverable from this window. Every gendered token belongs to someone else: Percival (\"shook HIS head\", \"He glanced to Aleks, licking at HIS lips\"), Wulfric (\"He signed the wheel... as he pressed HER blackened knuckles ", + "возражения": [ + "Layer mislabel (does not change the verdict): the list is titled 'narration clauses', but at least three items are Celene's QUOTED DIRECT SPEECH inside the inner story, not narration — 'Where I was supposed to be, Percival!' and 'I was watching the Whisper!' are her shouted reply to Percival, and 'I made sure of it' is the tail of her spoken answer to Wulfric ('No. No, Master. None marked my path here, I made sure of it'). Since the speaker is the narrator herself the Russian gender ending is the same either way, so the conclusion survives; but the three-layer bookkeeping the brief demands is wrong here.", + "'Where was I?' is ambiguous between a spoken echo of Percival's question and inner narration — it sits in the same paragraph as the narrative 'My eyes narrowed'. It still marks gender in Russian ('Где я была?') and still belongs to the narrator, so it is harmless, but it should not be presented as settled narration.", + "Aleks is unambiguously female in this window ('he pressed HER blackened knuckles', 'a full-grown woman'), and she is the only in-window character whose gender is fixed besides Percival and Wulfric. She is correctly absent from the speakers list (she only 'moans in agony', never speaks), but her femaleness must not be allowed to bleed onto the narrator by proximity — the narrator and Aleks are distinct people ('They spotted me and Aleks' is Percival's line about himself and Aleks, not the narrator's).", + "The outer frame (Jean-François, third person) is entirely absent from this ~1600-char window — every paragraph opens with a stray “‘ and belongs to the inner story. Any reading that tried to source the narrator's gender from frame attributive verbs would be unfounded here; nothing in the file is frame text.", + "Borderline omission from the clause list: 'I'd no time to run errands for you!' Its natural Russian rendering is impersonal ('мне некогда было бегать по твоим поручениям'), in which case it marks nothing and is rightly omitted — but a rendering as 'я не могла' would mark. It is the one item whose exclusion depends on a translation choice rather than on grammar, and it deserved a note. Conversely, 'My eyes narrowed', 'shaking my head', 'my senses were not as sharp' and 'None marked my path here' are correctly excluded: none of them can carry a narrator gender ending." + ] + } + ], + "круг1_сырой": { + "род": "female", + "первое_лицо": true, + "сверка": [ + { + "согласен": true, + "свой": "ж" + }, + { + "согласен": true, + "свой": "ж" + } + ] + } + }, + "8e50448cea": { + "род_голоса": null, + "голос": "неизвестно", + "определим_по_окну": false, + "уверенность": "high", + "улики_голоса": [], + "говорящие": [], + "иноязычные_вставки_агентов": [], + "латиница_законна": [], + "приёмы_агентов": [], + "приёмы": [], + "клаузы_повествования": [ + "I limped about in search of my boots" + ], + "клаузы_речи": [], + "слои": "Рамки (3 л., хронист) в окне НЕТ вовсе: ни одной фразы про Jean-François или про слушающего/записывающего. Всё окно — ВНУТРЕННИЙ РАССКАЗ от 1 л. в прошедшем времени: первая фраза («an uneasy day passed, most of our company…») идёт без открывающей кавычки, потому что окно вырезано из середины абзаца, а дальше каждый новый абзац открывается непарной “ («It was near sunset when we heard movement», «Ever watching», «The houndboy scrambled…», «Would she be different now?», «We saw movement…»). Внутри рассказа — ЦИТИРУЕМЫЕ реплики одного говорящего, «the fleshwitch»: ‘Joaquin!’ и ‘Bring them, lad!’; в них первого лица нет вовсе. Риторические вопросы «Would she be different now? Would she still be their Dior? Daughter? Sister? Messiah?» — несобственно-прямая речь самого рассказчика (коллективное «мы»), не отдельная реплика.", + "заметки": "ПОЛ НЕ УСТАНАВЛИВАЕТСЯ ПО ЭТОМУ ОКНУ. Рассказчик ни разу не назван по имени, к нему никто не обращается, и ни одного he/she/his/her на него не наведено. Все местоимения 3 л. в окне замкнуты на ДРУГИХ: «Phoebe dashed toward Dior’s chapel» и «he ran to Phoebe» / «The houndboy scrambled to his feet» (Joaquin — мальчик, его называют «lad»), «Would she still be their Dior», «Her eyes were ringed by awful shadows» (Dior). Пол ни одного из них на рассказчика не переносится — цепочка не замыкается, поэтому voice_gender=unknown, а не догадка по контексту серии.\n\nЕдинственная клауза, которая по-русски ОБЯЗАНА встать в 1 л. ед. ч. прошедшего времени (и значит пометить род): «I limped about» → «я хромал/хромала». Это единственная точка, где переводчик вынужден выбрать род, и по окну выбрать его не из чего.\n\nСознательно НЕ включены в narration_clauses:\n· «we heard movement», «we saw a cadre of hundreds marching out», «We saw movement, heart in throat», «marched toward us», «most of our company», «our former feet» — 1 л. МНОЖ. числа; русское прошедшее во мн. ч. род не метит («мы услышали/увидели»);\n· «My legs were almost hale now» — подлежащее «ноги», не «я»: «мои ноги были» рода голоса не выдаёт;\n· «finding them in a slurry of bloodstained frost», «tipping the remains… from within», «Looking toward the gatekeep» — причастные обороты при том же «я», по-русски естественно ложатся в деепричастия (найдя, вытряхнув, взглянув), род не метящие. Если переводчик развернёт их в личные формы («я нашёл/нашла», «вытряхнул/вытряхнула»), появятся ДОПОЛНИТЕЛЬНЫЕ точки рода — но это его решение, а не принуждение текста; принудительная точка ровно одна.\n\nЦитируемые реплики: у «the fleshwitch» (‘Joaquin!’ / ‘Bring them, lad!’) — только императив и вокатив, «я + прошедшее» нет, поэтому quoted_speakers и dialogue_clauses пусты. Пол самой fleshwitch по окну тоже прямо не назван.\n\nРазрядки буквами через пробел и капса целым словом в окне нет. Французских вставок нет: «House Augustin», «Dior», «Phoebe», «Maryn», «Reyne», «Joaquin» — имена собственные (транслитерация, а не сохранение чужеязычности), «cadre» — обычное английское слово. Мелочь исходника: «the remains of our former feet» выглядит как опечатка вместо «former owner’s feet» — на разбор слоёв и род не влияет.", + "адъюдикация": "", + "круг2_сверка": [ + { + "согласен": true, + "свой": null, + "имя": "неизвестно", + "улика": "Слоёв в окне два. Рамка (3 л.) в этом отрывке почти не видна — хронист не появляется ни разу. Внутренний рассказ идёт от «я» и открывается непарными кавычками: «It was near sunset when we heard movement», «‘Joaquin!’ the fleshwitch cried», «We saw movement, heart in throat». Носитель «я» в окне ровно один и опознаётся одной фразой: «My legs were almost hale now, and I limped about in search of my boots» (единственные вхождения I и my во всём файле — проверено грепом: 1×I, 1×my, 2×we, 2×our, 1×us). Этот рассказчик — участник отряда («our company», «the Emperor’s men marched toward us»), раненны", + "возражения": [ + "Вывод совпадает, но список улик пуст — а это не то же самое, что «улик нет». В окне есть положительная улика существования голоса: «My legs were almost hale now, and I limped about in search of my boots» плюс «we/our/us» (our company, marched toward us). Её надо было предъявить: она отделяет ответ «пол не устанавливается» (unknown) от ответа «внутреннего рассказа в окне нет» (no_voice), а с пустым списком эти два случая неразличимы, и проверяющий не может убедиться, что рассказчик вообще был найден.", + "Не зафиксировано, что рассказчик в окне безымянен и не совпадает ни с одним из названных лиц (Phoebe, Dior, Maryn, Reyne, Joaquin). Без этого шага «неизвестно» выглядит как отказ от разбора, а не как результат исключения кандидатов.", + "Не разобрана единственная ловушка окна — «the men who’d put so much faith in her» в последней строке. Это место соблазняет достроить мужской род рассказчику; надо было явно показать, почему оно не работает (рассказчик в это «men» не включён, отряд смешанный — Фиби рядом), иначе следующий читатель наступит на него повторно.", + "Не отмечено, что мужской маркер в окне есть, но принадлежит НЕ рассказчику: «lad» и «the houndboy… he ran» — это Joaquin, причём «lad» звучит внутри цитируемой реплики Фиби. Это ровно тот третий слой (реплика внутри внутреннего рассказа), где род принадлежит цитируемому, а не голосу; пустой список улик оставляет риск, что эту разницу не отследили." + ] + }, + { + "согласен": true, + "свой": null, + "имя": "неизвестно", + "улика": "Окно целиком (кроме двух цитат) — внутренний рассказ от 1 л.: открывающая фраза «And so, an uneasy day passed, most of our company…» уже содержит «our», т.е. это тот же слой, у которого просто срезана открывающая кавычка; дальше «It was near sunset when we heard movement», «we saw a cadre…», «We saw movement, heart in throat…». Все эти клаузы — 1 л. МНОЖЕСТВЕННОГО числа: в русском «мы услышали/увидели» рода не метит. Единственная клауза 1 л. ед. ч. в прошедшем — «I limped about in search of my boots» (ковылял/ковыляла) — она же единственная обязанная выбрать род; сопутствующие «finding them…»,", + "возражения": [ + "Список цитируемых говорящих пуст неточно: прямая речь в окне ЕСТЬ — «‘Joaquin!’ the fleshwitch cried. ‘Bring them, lad!’», говорящая — the fleshwitch (по контексту Maryn). На вердикт о рассказчике это не влияет (обращено к Joaquin, вокатив + императив рода говорящей в русском не метят), но как перечень слоя список неполон.", + "Не отмечено, что открывающее предложение «And so, an uneasy day passed, most of our company…» вопреки отсутствию открывающей кавычки принадлежит ВНУТРЕННЕМУ слою (маркер — «our»), а не рамке; ошибка слоя здесь не сработала, но разметка слоёв в выводе не проговорена, и при другом отрывке та же небрежность даёт неверный слой.", + "Не зафиксирован капкан «My legs were almost hale now»: это 1 л. по притяжательному, но подлежащее — «ноги», род существительного, а не рассказчика; клаузу правильно не внесли в список, однако без явной пометки её легко добавить туда при следующем проходе." + ] + } + ], + "круг1_сырой": { + "род": "unknown", + "первое_лицо": true, + "сверка": [ + { + "согласен": true, + "свой": null + }, + { + "согласен": true, + "свой": null + } + ] + } + }, + "90a20cb443": { + "род_голоса": null, + "голос": "неизвестно", + "определим_по_окну": false, + "уверенность": "high", + "улики_голоса": [], + "говорящие": [], + "иноязычные_вставки_агентов": [ + "gens d'armes", + "liathe" + ], + "латиница_законна": [], + "приёмы_агентов": [ + { + "вид": "капс целым словом", + "текст": "VAMPYR" + } + ], + "приёмы": [], + "клаузы_повествования": [ + "By the time I was done" + ], + "клаузы_речи": [], + "слои": "Внешней рамки (3 л., хронист) в этом окне нет вовсе: отрывок целиком — ВНУТРЕННИЙ РАССКАЗ от 1 лица в прошедшем времени, типографски размеченный непарными “‘ в начале абзацев (первый абзац обрезан, кавычка утеряна). Рассказчик безымянный, действует вместе с Wulfric, Percival и «моим мастером», несёт раненую Aleks из приората и рубится с солдатами. Третий слой — ЦИТИРУЕМЫЕ внутри рассказа реплики: мольба Aleks («D-don't let me die, Master»), ответ мастера («Fear not, my brave liathe…») и крик женщины из толпы («Vampyr! God help us, VAMPYR!»); ни в одной из них нет «я + прошедшее время».", + "заметки": "Пол голоса по ЭТОМУ окну не устанавливается. Рассказчик ни разу не назван по имени, к нему никто не обращается, местоимений he/she в его адрес нет; он лишь отделён от прочих («Percival and I behind», «tossed me a sword», «My master»). Женский род в окне принадлежит НЕ рассказчику: Aleks («she cried out», «her fangs», «her face», «her blinded eyes») — та, кого несут; Grace — кошка («Grace looking distinctly displeased … her evening»); женщина в толпе («a woman raising one finger»). Пол «мастера» тоже не назван. Цепочка «тот, кто говорит „я“» → «он/она» не замыкается, поэтому voice_gender=unknown.\n\nРод в русском вынужденно метится ровно в одной точке внутреннего рассказа: «By the time I was done» → «Когда я закончил/закончила». Все прочие глаголы рассказа — 1 л. МНОЖЕСТВЕННОГО числа (we ran / we could hear / we fled / we put them down), а множественное прошедшее рода не метит; «tossed me a sword» — косвенное дополнение, рода не требует; «Percival and I behind» — безглагольная конструкция.\n\nЦитируемые реплики рода не требуют: у Aleks — императивы («don't let me die/b-burn»), у мастера — императив и будущее («Fear not… will be thine»), у женщины — восклицание. Поэтому dialogue_clauses и quoted_speakers пусты.\n\nИноязычное: «gens d'armes» — французское, обязано остаться чужим (не «жандармы» современного вида). «liathe» — не французское, а внутримировой термин-обращение мастера, тоже должно остаться чужим словом, а не переводиться нарицательным. «Vampyr» в крике женщины — намеренно архаичное/чуждое написание, стоит удержать инаковость написания; в список иноязычных вставок не вынесено, так как слово всё же переводимо. «San Yves» — топоним, передаётся транслитерацией, чужим не сохраняется.\n\nРазрядки буквами через пробел в окне нет; курсив/кавычки как приём в этот список по условию не идут.", + "адъюдикация": "", + "круг2_сверка": [ + { + "согласен": true, + "свой": null, + "имя": "неизвестно", + "улика": "Внутренний рассказ (весь отрывок — цитатный слой, абзацы открываются непарными “‘) ведётся от первого лица в прошедшем: «By the time I was done…», «Percival and I behind», «Percival dropped Grace and tossed me a sword», «as we put them down». Рассказчик — отдельный, четвёртый персонаж: не Wulfric («Wulfric had returned, informing us»; «My master lifted Aleks» + «Wulfric in front, Aleks in his arms» ⇒ master = Wulfric) и не Percival («Percival and I»). Имя рассказчика в окне не названо. Ни одного родового маркера на это «я» нет: все гендерные местоимения принадлежат другим — Aleks («she cried o", + "возражения": [ + "Вердикт совпадает, возражений по существу нет: пол рассказчика из этого окна действительно не устанавливается, имя не названо.", + "Претензия процедурная: пустой список улик. «Unknown» здесь — не отсутствие голоса, а положительный факт о вполне локализуемом голосе: в окне есть первое лицо, отличное от Wulfric, Percival и Aleks, слуга/спутник Wulfric («My master»), вооружённый и участвующий в убийстве солдат, судя по «the monsters among them» — такой же вампир. Стоило зафиксировать хотя бы то, что все гендерные местоимения окна (she/her — Aleks и кошка Grace, his — Wulfric) принадлежат другим персонажам, а на рассказчика не приходится ни одного: именно это и есть улика в пользу unknown." + ] + }, + { + "согласен": true, + "свой": null, + "имя": "неизвестно", + "улика": "Пол рассказчика внутреннего рассказа по этому окну НЕ устанавливается. Все его самоупоминания: \"By the time I was done\" (единственная клауза, обязанная метить род: закончил/закончила), \"My master lifted Aleks\" (подлежащее — мастер, не рассказчик), \"Percival and I behind\" (безглагольный оборот, и он же ОТДЕЛЯЕТ рассказчика от Персиваля), \"tossed me a sword\" (рассказчик — дативный объект, \"мне\" рода не метит). Остальное повествование — \"we ran / we could hear / we fled / we put them down\": множественное число, рода нет. Все гендерные местоимения окна принадлежат ДРУГИМ: Aleks — \"her fangs\", \"her", + "возражения": [ + "Список цитируемых говорящих указан пустым — []. Это неверно как описание слоя: в окне три цитируемые реплики — Aleks (\"D-don’t let me die, Master. Please, don’t let me b-burn\"), мастер (\"Fear not, my brave liathe. The kingdom of God will be thine\") и безымянная женщина из толпы (\"Vampyr! God help us, VAMPYR!\"). Двое из них установлены как женщины (Aleks — \"her fangs\", \"her face\", \"she cried out\"; \"a woman raising one finger and screaming in the night\"). Пустой список защитим только при узком чтении «говорящие, чьи реплики обязаны метить род»: реплика Aleks — императив + инфинитив (\"не дай мне умереть / сгореть\"), реплика мастера — императив + будущее (\"will be thine\"), крик женщины — императив; ни одна рода не метит. Но как перечень цитируемых говорящих [] ошибочно.", + "Реплика Aleks \"don’t let me die, Master\" — потенциальная ловушка приписывания слоя: обращение \"Master\" адресовано мастеру рассказчика, а само \"my master\" стоит в ПОВЕСТВОВАНИИ. Ни то, ни другое рода рассказчика не метит, и в улики попасть не должно.", + "Обращение \"my brave liathe\" адресовано Aleks, а не рассказчику: если бы кто-то принял его за обращение к рассказчику, получилась бы улика о ДРУГОМ персонаже, выданная за улику о голосе." + ] + } + ], + "круг1_сырой": { + "род": "unknown", + "первое_лицо": true, + "сверка": [ + { + "согласен": true, + "свой": null + }, + { + "согласен": true, + "свой": null + } + ] + } + }, + "b065a92dc0": { + "род_голоса": null, + "голос": "неизвестно", + "определим_по_окну": false, + "уверенность": "high", + "улики_голоса": [], + "говорящие": [], + "иноязычные_вставки_агентов": [ + "Château Impérial" + ], + "латиница_законна": [], + "приёмы_агентов": [], + "приёмы": [], + "клаузы_повествования": [], + "клаузы_речи": [], + "слои": "Окно целиком лежит во ВНЕШНЕЙ РАМКЕ. Рамочное повествование — третьим лицом о хронисте и о слушаемом им герое: «The siblings glowered at each other then», «Jean-François looked up from his tome. He saw the silversaint was still staring across the river», «the Last Silversaint had seemed a giant», «As Gabriel stared at Celene, Jean-François could see pain in his gaze». ЦИТИРУЕМЫЕ РЕПЛИКИ — это реплики рамочного диалога: длинный вопрос Jean-François («The revelation that your daughter Patience had risen Dead… I am wondering what possessed the husband of a murdered wife…») и односложный ответ Gabriel («Almost»). ВНУТРЕННЕГО РАССКАЗА (первое лицо, прошедшее время, рассказ героя хронисту) в этом окне НЕТ вовсе: оно вырезано ровно на стыке — хронист ещё только задаёт вопрос, с которого рассказ должен начаться, а сам рассказ за границей отрывка.", + "заметки": "1) Первое лицо в окне есть, но ТОЛЬКО в рамочной реплике хрониста и только в НАСТОЯЩЕМ времени: «as I say», «One I find difficult to bridge», «I am wondering what happened…», «I am wondering what possessed…». Настоящее время рода в русском не метит, поэтому в dialogue_clauses ничего не идёт; по правилу задачи («I fear»-тип не включаем) эти клаузы отброшены сознательно, а не по недосмотру.\n2) Ответ Gabriel — «Almost» — безглагольный, рода не даёт.\n3) Прошедшее время в окне всё третьеличное и принадлежит рамке: «The siblings glowered», «the historian was secretly delighted», «Jean-François looked up», «He saw», «they'd first met», «Jean-François stepped into his cell», «the Last Silversaint had seemed a giant», «A man who had begun carving his story», «Jean-François could see pain in his gaze», «the man himself seemed small now». Род там задаётся персонажем (he/Jean-François/Gabriel), а не голосом «я».\n4) Пол героя рамки прочитывается однозначно (Gabriel de León, «the husband of a murdered wife, and the father of a daughter Dead», «his gaze», «the man himself»), и пол хрониста-мужчины тоже (Jean-François). Но это улики РАМКИ, а не внутреннего рассказа: цепочка «тот, кто говорит „я“ в внутреннем слое» → «он/она» здесь не замыкается просто потому, что внутреннего слоя в окне нет. Именно поэтому voice_gender = no_voice, а не male: переводчик этого окна не переводит ни одной формы 1 л. ед. ч. прошедшего времени.\n5) Собственные имена (Fabién, Reyne á Maergenn, Jean-François, Gabriel de León, Celene, Patience) в foreign_inserts не внесены: в русском они транслитерируются, а не сохраняются чужими. «Château Impérial» — единственный оборот, который перевод обязан оставить иноязычным (название резиденции).\n6) Технический след исходника: в «had seemed a giant .» и «was a legend living .» перед точкой стоит лишний пробел — почти наверняка след снятого курсива (giant / living). Как типографский приём по условию задачи (разрядка/капс) это не квалифицируется, но при сверке форматирования учитывать стоит. Заглавные «Dead», «Prince of Forever», «Grail», «Last Silversaint» — авторская капитализация терминов, тоже не разрядка и не капс целым словом, потому в typographic_devices не внесены.", + "адъюдикация": "", + "круг2_сверка": [ + { + "согласен": true, + "свой": null, + "имя": "нет голоса (окно целиком во внешней рамке; внутренний рассказ здесь не звучит)", + "улика": "Окно целиком относится к ВНЕШНЕЙ РАМКЕ, повествование третьим лицом от лица хрониста: «But the historian was secretly delighted that neither uttered a word», «Jean-François looked up from his tome. He saw the silversaint was still staring across the river», «As Gabriel stared at Celene, Jean-François could see pain in his gaze». Ни один абзац не открывается непарной кавычкой с повествованием от первого лица в прошедшем времени — то есть куска внутреннего рассказа в окне НЕТ.\n\nЕдинственные кавычки в окне — это ЦИТИРУЕМЫЕ РЕПЛИКИ рамочного диалога, а не внутренний рассказ:\n1) хвост речи хрониста", + "возражения": [ + "Вердикт совпал (no_voice), но список улик у другого читателя ПУСТ, а вывод «внутреннего рассказа здесь нет» требует позитивного обоснования: в окне есть кавычки и есть «I», и без разбора это выглядит как непрочитанный отрывок. Обоснование должно называть, что все кавычки — рамочный диалог (хвост речи хрониста + односложное «Almost», Gabriel murmured), а все «I» («as I say», «I find difficult to bridge», «I am wondering») принадлежат Jean-François, говорящему вслух в рамке." + ] + }, + { + "согласен": true, + "свой": null, + "имя": "неизвестно", + "улика": "Я разобрал окно по слоям и подтверждаю: внутреннего рассказа (1 л., прош. вр., рассказчик) в этом отрывке НЕТ ни одной клаузы.\n\n1) Кавычек в окне ровно две пары («“…”» — 2 открывающих, 3 закрывающих, третья закрывает обрывок, с которого окно начинается). Обе — прямая речь РАМОЧНОГО уровня, а не внутренний рассказ:\n · обрывок «…had risen Dead… and the murder of Reyne á Maergenn.”» — конец реплики хрониста: сплошное обращение на «вы» (your daughter, Your sister, your failed attempt), значит говорит НЕ тот, о ком речь;\n · «“But as I say, there is a gulf here, Silversaint… A creature he hated ", + "возражения": [ + "Не блокирующее уточнение к терминологии, вывод не меняет: пустой список «цитируемых говорящих» верен только в узком смысле — «говорящие ВНУТРИ внутреннего рассказа». В самом окне прямая речь есть, и говорящих двое: Jean-François (длинная реплика-вопрос, «as I say», «I am wondering») и Gabriel («Almost,» Gabriel murmured). Оба принадлежат рамочному слою. Если реестр окна собирает всех цитируемых говорящих, а не только вложенных во внутренний рассказ, то [] — недоучёт; если только вложенных, [] правильно, потому что вкладывать не во что." + ] + } + ], + "круг1_сырой": { + "род": "not_applicable", + "первое_лицо": false, + "сверка": [ + { + "согласен": true, + "свой": null + }, + { + "согласен": true, + "свой": null + } + ] + } + }, + "c3517980c7": { + "род_голоса": null, + "голос": "Gabe", + "определим_по_окну": false, + "уверенность": "medium", + "улики_голоса": [ + "‘Gabe!’", + "The cry pulled me from reverie, back into the dim light of day.", + "‘Gabe, it’s astonishing, ’ Baptiste said", + "‘Fairdawning, brother.’ I nodded to the big man. ‘What news?’" + ], + "говорящие": [], + "иноязычные_вставки_агентов": [], + "латиница_законна": [], + "приёмы_агентов": [], + "приёмы": [], + "клаузы_повествования": [ + "I’d dreamed of Celene almost every night", + "since I’d drunk her blood in Cairnhaem", + "I nodded to the big man" + ], + "клаузы_речи": [], + "слои": "Внешней рамки (3 л., хронист) в этом окне нет вовсе: каждый абзац открывается непарной “ — весь отрывок целиком есть ВНУТРЕННИЙ РАССКАЗ от первого лица в прошедшем времени («Down long thoroughfares we walked», «I nodded to the big man»), выдранный из середины, без закрывающих кавычек. Внутри него — цитируемые реплики в одинарных кавычках: Шарлотта («‘Come.’ … ‘The forge is this way.’»), сам рассказчик («‘Fairdawning, brother.’ … ‘What news?’»), Батист («‘Gabe!’», «‘Gabe, it’s astonishing, ’»), плюс безымянная заикающаяся реплика в начале («Looks nothing like h-h-him.») и вспоминаемая семейная присказка («Ever outnumbered, we’d say. Never outmatched. Always Lions.»), поданная как цитата с плюральным тегом. Третье лицо внутри рассказа (Charlotte bowed, Baptiste was striding) — это персонажи внутреннего слоя, а не рамка.", + "заметки": "Цепочка на имя замыкается жёстко: крик ‘Gabe!’ — и тут же «The cry pulled me from reverie», то есть окликнули именно того, кто говорит «я»; подтверждение — «‘Gabe, it’s astonishing, ’ Baptiste said», обращение по имени к рассказчику. Прямой грамматической улики (he/him о рассказчике, согласования) в окне НЕТ; пол опирается на две косвенные: (1) обращение к голосу по мужскому имени Gabe, (2) сам голос приветствует крупного мужчину как «brother» — мужски-кодированное братское обращение. Отсюда confidence=medium, а не high. Обратные улики отсутствуют: все явно женские фигуры окна отделены от «я» — «my cousin’s eye as she approached» (Шарлотта), «my sister and me playing soldiers», «looking at me and Lachie» (Лаки — спутник, не рассказчик), Celene упомянута только как объект сна. Что НЕ попало в narration_clauses и почему: «Down long thoroughfares we walked», «Ever outnumbered, we’d say», «my sister and me playing soldiers» — множественное число, русское прошедшее там рода не метит («мы шли», «мы играли»); «reminding me at once of my stepfather’s forge», «The cry pulled me from reverie», «Memory of my nightmare rose» — подлежащее третьего лица, «мне/меня» рода не несёт; «Looks nothing like h-h-him» — цитируемая реплика без первого лица. Три выписанные клаузы — единственные точки, где переводчик обязан выбрать род: «мне снился/снилась» или «я видел/видела во сне», «я выпил/выпила её кровь», «я кивнул/кивнула». Заикание «h-h-him» — дефис-приём, не разрядка и не капс, поэтому в typographic_devices не идёт. Французских вставок в окне нет: имена (Charlotte, Baptiste, Celene, Eloise) в русском транслитерируются, а «Fairdawning» — англоязычный выдуманный привет, чужим его сохранять не требуется; «blackthumb», «sign of the wheel», «Always Lions» — тоже английские реалии, не иноязычные вставки.", + "адъюдикация": "Строитель назвал «м», ОБА проверяющих — «не устанавливается», и они правы по существу: улики ‘Gabe!’ и «The cry pulled me from reverie» замыкают ИМЯ, а не пол, а «brother» в «‘Fairdawning, brother.’ I nodded to the big man» — вокатив В АДРЕС Батиста, то есть метит пол адресата. Прямой грамматической улики о рассказчике в окне нет. Принято: не устанавливается.", + "круг2_сверка": [ + { + "согласен": false, + "свой": null, + "имя": "Gabe", + "улика": "Слой определён однозначно: весь отрывок — ВНУТРЕННИЙ рассказ от 1 л. в прошедшем (каждый абзац открывается непарной “, рамки хрониста в окне нет вообще). Имя рассказчика в окне названо: оклик «‘Gabe!’» → «The cry pulled me from reverie» — окликают того, кто говорит «я», значит рассказчик = Gabe. Дальше проверил ВСЕ гендерно-маркированные токены окна (grep: he/him/his ×5, she/her ×5, man, brother, sister, fellow ×2) — ни один не сидит на «я»: «her sword and shield» — Eloise; «her blood» — Celene; «she approached / she passed / she led us» и «my cousin» — Charlotte; «him» в «walked beside him», ", + "возражения": [ + "Имя названо верно — Gabe, и слой опознан верно (внутренний рассказ от 1 л., не рамка). Расхождение только в поле пола: male не обосновано содержимым окна.", + "Улика «‘Fairdawning, brother.’ I nodded to the big man. ‘What news?’» прочитана наоборот. «brother» — вокатив, адресованный Baptiste, и это подтверждает сам текст следующей клаузой: «I nodded to the big man». Слово маркирует пол АДРЕСАТА (Baptiste), а не говорящего. Как улика на пол рассказчика оно не работает вовсе.", + "Улики «‘Gabe!’» и «The cry pulled me from reverie, back into the dim light of day» устанавливают ИМЯ рассказчика (оклик замыкается на «me»), но не его пол. Это идентификация голоса, а не гендерный маркер.", + "Улика «‘Gabe, it’s astonishing,’ Baptiste said» — повторное обращение по тому же имени, никакой новой информации о поле не добавляет; в цепочке она дублирует первую.", + "Таким образом все четыре предъявленные улики сводятся к одному-единственному основанию — «Gabe звучит по-мужски». Это ровно та догадка по типу имени, которая по условию замера уликой не является. Цепочка на «я» не замкнута → законный ответ unknown.", + "Дополнительно проверено исполнением (grep по всем he/him/his/she/her/man/woman/brother/sister/fellow): в окне нет НИ ОДНОГО гендерно-маркированного слова, относящегося к «я». «my sister» маркирует сестру, «my cousin … she» — Charlotte, «her blood» — Celene, «her sword» — Eloise, «the big man»/«he»/«his back» — Baptiste, «A handsome fellow»/«his hands» — безымянный blackthumb, «h-h-him» — статуя. Предикатива вида «I was a man/boy» нет, английский past рода не несёт.", + "Практическое следствие для замера: русский перевод этого окна обязан выбрать род в «I nodded» (кивнул/кивнула) и в «we walked», не имея на то улик внутри окна, — значит выбор male здесь опирается на внешнее знание (сериал/остальная книга), а не на текст. Засчитывать male как «установлено из окна» = загрязнить эталон тем самым знанием, которое замер должен изолировать." + ] + }, + { + "согласен": false, + "свой": null, + "имя": "Gabe", + "улика": "Слой определён верно: всё окно — ВНУТРЕННИЙ рассказ (каждый абзац открывается непарной “/‘, рамки с Jean-François в окне нет). Имя рассказчика доказано и цепочка замыкается: оклик «‘Gabe!’» → «The cry pulled me from reverie, back into the dim light of day» (оклик выдернул именно «me»), подтверждение — «‘Gabe, it’s astonishing, ’ Baptiste said». Имя = Gabe, здесь возражений нет.\n\nПОЛ по этому окну НЕ устанавливается. Всех 1sg-глаголов ровно три: «I’d dreamed of Celene almost every night», «since I’d drunk her blood in Cairnhaem», «I nodded to the big man» — ни один не несёт лексического указани", + "возражения": [ + "Пол назван, хотя окном не устанавливается. Улики 1–3 («‘Gabe!’», «The cry pulled me from reverie», «‘Gabe, it’s astonishing,’ Baptiste said») доказывают ИМЯ, а не пол — они лишь замыкают адресата оклика на «me». Ни к «I», ни к «me» в окне не приложено ни одного родового слова или согласования. Единственная опора на «male» — это Gabe → Gabriel, то есть догадка по типу имени, прямо дисквалифицированная условием.", + "Улика о ДРУГОМ персонаже принята за улику о рассказчике: «‘Fairdawning, brother.’ I nodded to the big man. ‘What news?’». «brother» — вокатив В АДРЕС Баптиста, «the big man» — он же; оба слова метят пол АДРЕСАТА. Пол говорящего отсюда не выводится (женщина тоже может сказать «brother»), а в русском вокатив «брат» рода говорящего не метит вовсе. Симметрично «a fellow blackthumb» — «fellow» тут «собрат по ремеслу» при существительном, а не «мужчина», и относится к бритоголовому спутнику Баптиста.", + "«I’d dreamed of Celene almost every night» в списке обязанных пометить род — сомнительно: идиоматический перевод «мне снилась Селена почти каждую ночь» — дативно-безличный оборот, согласования с рассказчиком в нём нет; род появится только при выборе варианта «я видел во сне». Клауза не ОБЯЗЫВАЕТ метить род, в отличие от бесспорных «I’d drunk her blood» (выпил/выпила) и «I nodded» (кивнул/кивнула).", + "Список цитируемых говорящих пуст, хотя внутри рассказа их минимум трое: заикающаяся неатрибутированная реплика «Looks nothing like h-h-him.», Шарлотта («‘Come.’ … ‘The forge is this way.’») и Баптист («‘Gabe, it’s astonishing, ’»). На итог замера это не влияет — ни одна их реплика не содержит родомечущей клаузы (императив, настоящее время), — но перечень как факт неполон.", + "Полнота списка клауз рассказчика в остальном верна, и это стоит зафиксировать против соблазна добрать улик: «we walked», «we’d say», «my sister and me playing soldiers» — множественное число, род в русском прошедшем не метят; «The cry pulled me» — рассказчик в винительном, подлежащее не он. Добавить туда нечего, а значит и опоры для «male» взять неоткуда." + ] + } + ], + "круг1_сырой": { + "род": "male", + "первое_лицо": true, + "сверка": [ + { + "согласен": true, + "свой": "м" + }, + { + "согласен": true, + "свой": "м" + } + ] + } + }, + "d3237e1dea": { + "род_голоса": "ж", + "голос": "Celene (Celene Castia, «The Last Liathe»)", + "определим_по_окну": true, + "уверенность": "high", + "улики_голоса": [ + "the more afraid I became.” The Last Liathe fell silent, black eyes on dark waters.", + "Jean-François had found himself caught up in the battle, quill flowing swift as Celene spoke.", + "he glanced up, brow arched. “Of what were you afraid, M lle Castia?”", + "Still Celene was mute. Her legs were crossed beneath her upon the oily stone, elbows on her knees, fingers steepled at her lips.", + "though she was silent, Jean-François wondered if she was speaking to the ones inside her head. “M lle Cast—” “My grandfather was a genius." + ], + "говорящие": [], + "иноязычные_вставки_агентов": [ + "M lle Castia", + "M lle Cast—" + ], + "латиница_законна": [], + "приёмы_агентов": [], + "приёмы": [], + "клаузы_повествования": [ + "the more afraid I became" + ], + "клаузы_речи": [], + "слои": "Рамка (3 л.): всё между кавычками — «The Last Liathe fell silent, black eyes on dark waters», «Jean-François had found himself caught up in the battle, quill flowing swift as Celene spoke», «Still Celene was mute… She seemed a statue then», плюс вопрос хрониста «Of what were you afraid, M lle Castia?» и его оборванный оклик «M lle Cast—». Внутренний рассказ (1 л., прошедшее) — два куска в непарных кавычках: конец предыдущего абзаца («We'd witnessed the aftermath… the more afraid I became.») и возобновление после паузы («My grandfather was a genius… it was Fabién who first saw their utility.»). Цитируемых реплик ВНУТРИ внутреннего рассказа в этом окне нет: реплики Жана-Франсуа принадлежат рамке, а не рассказу Селены.", + "заметки": "Цепочка замкнута трижды и независимо: (1) реплика с «I became» обрывается закрывающей кавычкой, и тут же субъектом становится The Last Liathe → она и есть говорящая; (2) рамка прямо называет говорящую — «quill flowing swift as Celene spoke»; (3) хронист переспрашивает ровно ту клаузу («Of what were you afraid») и адресует её «M lle Castia» — женское обращение (Mademoiselle), после чего рамка ведёт Селену через she/her и она же возобновляет рассказ. Пол голоса = женский, догадка по имени не требовалась.\n\nПочему narration_clauses всего одна. Остальные глаголы внутреннего рассказа — 1 л. МНОЖЕСТВЕННОГО числа: «We'd witnessed the aftermath», «the deeper we carved our way», «We dwelled in secret». В русском прошедшее множественного числа рода НЕ метит (мы видели / мы вгрызались / мы жили), поэтому они в список не идут, хотя переводчику полезно помнить, что это тот же голос. «It pains me to say it» — настоящее время, исключено по правилу. «Fabién Voss may have been the most innovative military mind» и «it was Fabién who first saw their utility» — 3 л., род чужой (мужской), на голос не влияют.\n\nРазрядки и капса как приёма в окне нет. «M lle» — не разрядка, а типографский след верхнего индекса «M^lle» (сокращение Mademoiselle), при переводе должно остаться французским обращением, а не превратиться в «мисс»/«госпожа». Слово «abattoir» в «that abattoir, that butchery» — французский по происхождению, но в английском натурализован и стоит в синонимическом ряду с «butchery», поэтому в foreign_inserts не вынесен: его переводят («бойня»), чужим сохранять не обязаны. «Jean-François» — французское имя, но передаётся транслитерацией (Жан-Франсуа), это не вставка. «Dún Maergenn», «Dyvok», «Voss», «Liathe», «wretched», «kith», «daystar» — ономастика/термины мира, не французский слой.", + "адъюдикация": "", + "круг2_сверка": [ + { + "согласен": true, + "свой": "ж", + "имя": "Celene Castia (\"The Last Liathe\")", + "улика": "1) The first-person narration closes with \"...the more afraid I became.”\" and the very next frame line names who was speaking: \"The Last Liathe fell silent, black eyes on dark waters.\" 2) Explicit attribution of that first-person block: \"Jean-François had found himself caught up in the battle, quill flowing swift as Celene spoke.\" 3) Feminine honorific + surname addressed to that same speaker: \"“Of what were you afraid, M lle Castia?”\" (Mademoiselle). 4) Feminine pronouns for her in the frame: \"Still Celene was mute. Her legs were crossed beneath her upon the oily stone, elbows on her knees, f", + "возражения": [] + }, + { + "согласен": true, + "свой": "ж", + "имя": "Celene (Celene Castia, «The Last Liathe»)", + "улика": "Внутренний рассказ (1 л., прош.) обрывается на «...the more afraid I became.”», и сразу же рамка атрибутирует замолчавшего: «The Last Liathe fell silent, black eyes on dark waters». Следующая фраза рамки прямо называет говорившего: «quill flowing swift as Celene spoke» — хронист записывал со слов Celene, т.е. рассказ вела она. Тот же референт продолжается: «Still Celene was mute» (то же «замолчала»), «Her legs were crossed beneath her... fingers steepled at her lips», «She seemed a statue then», «whether she was speaking to the ones inside her head». Обращение Jean-François «Of what were you a", + "возражения": [ + "Слабое место не в выводе, а в мерке: единственная заявленная клауза «the more afraid I became» в русском род метит НЕ обязательно. Идиоматичный перевод «тем страшнее мне становилось» / «тем сильнее меня охватывал страх» — безличный, рода не несёт; род появляется лишь при выборе «тем больше я боялась». То есть окно может не содержать ни одной клаузы, ПРИНУЖДАЮЩЕЙ переводчика определиться, и «промах по роду» здесь фиксируется только если переводчик сам выбрал личную конструкцию. Клаузу из списка я не убираю, но её надо пометить как факультативно-гендерную, иначе замер даёт ложные нули.", + "Список «цитируемые говорящие» пуст формально верно (внутри рассказа Celene никого не цитирует), но в окне есть прямая речь второго лица — «Of what were you afraid, M lle Castia?» от Jean-François. Она принадлежит РАМКЕ, а не внутреннему рассказу; если разметка потом будет считать любые кавычки внутренним слоем, эта реплика мужского говорящего попадёт в рассказ Celene и испортит атрибуцию рода. Стоит зафиксировать её явно как frame-реплику.", + "Типографский признак «абзац открывается непарной кавычкой» здесь работает против наивного парсера: первый блок кавычкой НЕ открывается (окно выдрано из середины), зато ЗАкрывается ею, а второй блок «My grandfather was a genius» открывается кавычкой и является ПРОДОЛЖЕНИЕМ того же внутреннего рассказа после перебивки. Механическая склейка «кавычка = новая реплика» породит фантомного второго говорящего.", + "Улика №5 в чужом списке процитирована слипшейся: «“M lle Cast—” “My grandfather was a genius.» — это два разных слоя в одной строке (оборванное обращение Jean-François из рамки и возобновлённый рассказ Celene). Как улика она годна, но в таком виде провоцирует приписать «My grandfather was a genius» хронисту." + ] + } + ], + "круг1_сырой": { + "род": "not_applicable", + "первое_лицо": false, + "сверка": [ + { + "согласен": false, + "свой": "ж" + }, + { + "согласен": false, + "свой": "ж" + } + ] + } + }, + "eefdade2c3": { + "род_голоса": null, + "голос": "неизвестно", + "определим_по_окну": false, + "уверенность": "high", + "улики_голоса": [], + "говорящие": [ + { + "имя": "Dior (the Grail)", + "род": "ж", + "улика": "«Dior snatched up her goblet and took a long gulp»; «The Grail looked to the Empress... ‘… I must be crowned Empress of all Elidaen.’»; «‘I’ve thought about it!’ Dior declared» — та же говорящая, о которой сказано she/her: «And meeting the Empress’s eyes, she spoke»" + } + ], + "иноязычные_вставки_агентов": [], + "латиница_законна": [], + "приёмы_агентов": [], + "приёмы": [], + "клаузы_повествования": [], + "клаузы_речи": [ + { + "english": "I've thought about it!", + "speaker": "Dior (the Grail)", + "gender": "female" + } + ], + "слои": "Внешней рамки (3 л. про хрониста) в этом окне нет ни строки: весь текст идёт внутри непарных “ — это ВНУТРЕННИЙ РАССКАЗ, но ведётся он целиком в третьем лице (Isabella tilted her head; The Grail drew a long breath; Dior snatched up her goblet; It was the Pontifex...), рассказчик себя ни разу не называет. Третий слой — цитируемые реплики внутри рассказа, в одинарных ‘ ’: Дьор/Грааль («I have to sit the Fivefold Throne», «I’ve thought about it!»), Изабелла («Indeed?»), Гасконь («Y-you? Empress?»). Первое лицо встречается ТОЛЬКО в этих репликах, в самом повествовании его нет.", + "заметки": "Окно — сцена пира в тронном зале, изложенная рассказчиком-очевидцем, но его «я» в этот кусок не попало ни разу: ни I/me/my, ни we. Поэтому род глаголов внутреннего повествования по этому отрывку русский перевод пометить НЕ обязан — все past-формы повествования третьеличные и род берут от называемых персонажей (Isabella tilted → наклонила; Dior snatched → схватила; Reyne snatched/downed → схватила/осушила; the Pontifex... abandoned his attempt, falling → он; the High Inquisitrix softly scoffed → она; Prince Philippe looked incredulous → он). Единственная обязательная род-метка от первого лица — «I’ve thought about it!» Дьор (перфект → рус. прошедшее: «я уже подумала об этом»), род женский. Исключены сознательно: «I … I fear the price might not be so cheap» (настоящее, прямо оговорено в задании), «I have to be united / I have to sit / I must be crowned / I need to sit / I have to keep it» (настоящее и модальность будущего), «It doesn’t have to be forever» (настоящее). Клауза «the sword my forebear used to try and unify all Elidaen» даёт русское прошедшее, но подлежащее там — forebear (в тексте он мужчина: «the Fivefold Throne he sought to build»), а не «я», поэтому в dialogue_clauses не вносится. Французских вставок в окне нет: Philippe, Gascoigne, Reyne, Joaquin, Isabella, Dior — имена, а Pontifex / High Inquisitrix / Maidsfeast / soothsingers / Fivefold Throne — внутримировые титулы и реалии, они переводятся/транслитерируются, а не сохраняются чужими. Разрядки буквами и капса целым словом нет; пробелы в «‘ Empress? ’» — след курсива в исходной вёрстке, не разрядка.", + "адъюдикация": "Расхождение терминологическое, а не фактическое: строитель и второй проверяющий говорят «голоса нет», первый — «голос есть, но его первого лица в окно не попало». Операционно это одно и то же: клауз 1 л. прош. вр. в слое повествования НЕТ, класс к главе НЕПРИМЕНИМ. Принято так.", + "круг2_сверка": [ + { + "согласен": false, + "свой": null, + "имя": "неизвестно", + "улика": "Окно целиком — внутренний рассказ: каждый абзац открывается непарной “ (»“Isabella tilted her head«, »“The Grail drew a long breath«, »“Dior snatched up her goblet«, »“It was the Pontifex, red-faced«), третьеличной рамки хрониста в окне нет. Значит голос рассказчика присутствует. Но все 7 вхождений «I» лежат внутри вложенных одинарных кавычек и принадлежат цитируемому говорящему — Диор, она же the Grail: ‘I … I fear the price might not be so cheap as all that.’ / ‘The Esana Prophecy says I have to be united with the sword my forebear used…’ / ‘… I must be crowned Empress of all Elidaen.’ / ‘I'", + "возражения": [ + "Пол указан как no_voice, но это неверно: внутренний рассказ в окне есть и ведётся он одним голосом — все без исключения абзацы открываются непарной “, а третьеличных рамочных предложений (типа «The historian's eyes narrowed») в окне нет ни одного. Правильный ответ — unknown («голос есть, улик на пол нет»), а не no_voice («внутреннего рассказа нет»).", + "Разница не косметическая для замера: no_voice сообщает, что род подставлять негде, тогда как рассказчик здесь реально присутствует и на соседнем окне тот же голос потребует рода прошедшего времени; ошибка класса ответа исказит сравнение с переводом.", + "Возможная причина ошибки — принятие вложенных ‘…’-реплик Диор за весь текст: если счесть окно «сплошным диалогом», голос действительно кажется отсутствующим. Но ‘…’ вложены внутрь “-абзацев, то есть это цитируемые реплики ВНУТРИ повествования, а не само повествование." + ] + }, + { + "согласен": true, + "свой": null, + "имя": "неизвестно", + "улика": "Всё окно — внутренний рассказ: все 11 абзацев открываются непарной “ (рамочных клауз третьего лица про хрониста здесь нет вообще). Но повествовательный слой этого рассказа целиком третьеличный. Механическая проверка: после вырезания всех спанов ‘…’ (прямая речь) в остатке НЕТ ни одного первого лица — подлежащие только «Isabella tilted her head», «The Grail drew a long breath», «Reyne squeezed her hand, Joaquin watching…», «Dior snatched up her goblet», «Prince Philippe looked incredulous», «It was the Pontifex… his kerchief», «the dour High Inquisitrix softly scoffed», «Gascoigne managed to wh", + "возражения": [ + "Список цитируемых говорящих НЕПОЛОН — пропущена Изабелла. Реплика ‘Indeed?’ принадлежит ей («“Isabella tilted her head. ‘Indeed?’»), и она женского пола: «Empress Isabella sat motionless», «Isabella tilted her head», «Isabella’s brow rose», «the Empress’s eyes». В русском её слой метит род («склонила голову», «Императрица сидела неподвижно»).", + "Пропущен второй цитируемый говорящий — Gascoigne, он же Понтифик, мужского пола: «‘Y-you?’ Gascoigne managed to wheeze. ‘Empress?’» при описании «It was the Pontifex, red-faced… trying unsuccessfully to stifle HIS laughter with HIS kerchief. Eventually the OLD MAN abandoned his attempt… Beside HIM, the dour High Inquisitrix». Цепочка Понтифик→Гаскойн замыкается позиционно (реплика следует сразу за абзацем о его хохоте и приписана ему глаголом wheeze), но формального отождествления имени и титула в окне нет — это стоит отметить как «мужской, отождествление позиционное».", + "Улика по Диор верна, но одна её опора слабее, чем заявлено: в «Dior snatched up her goblet» местоимение her теоретически могло бы указывать на чужой кубок (ср. контрастное «Reyne snatched up her OWN goblet» ниже). Пол Диор всё равно доказан независимо — «The Grail drew a long breath… And meeting the Empress’s eyes, SHE spoke», плюс «The Grail looked to the Empress, eyes filled with childish hope» в той же реплике, что и «Dior declared». То есть вывод стоит, но держится на «she spoke», а не на «her goblet».", + "Пустой список клауз, обязанных пометить род, верен ДЛЯ РАССКАЗЧИКА, но может ввести в заблуждение как «в окне род метить нечему». В переводе род метится обильно — только у цитируемых: у Диор это «I have to sit / I need to sit / I must be crowned» (я должнА), «I’ve thought about it» (я думалА), «the sword my forebear used» — то есть первое лицо женского рода внутри реплик; и весь третьеличный слой (склонилА, схватилА, сиделА vs. пыталсЯ, бросил попытку). Если гейт считает клаузы по окну, эти позиции должны быть отнесены к Диор/Изабелле/Гаскойну, а не к пустому голосу рассказчика.", + "Кодовая оговорка по метке: типографски окно ЦЕЛИКОМ является внутренним рассказом (каждый абзац с “), то есть голос-рассказчик присутствует как говорящий — он просто не оставляет грамматического следа. Я ставлю no_voice в смысле «первого лица рассказчика в окне нет, гендерить нечего». Если кодбук резервирует no_voice за окнами БЕЗ внутреннего рассказа (чистая рамка), то корректным кодом здесь будет unknown. Существо вывода от этого не меняется: пол рассказчика по окну не устанавливается и ни одна клауза его не требует.", + "Первая реплика окна ‘I … I fear the price might not be so cheap as all that.’ не атрибутирована текстом. Правдоподобно это Диор (Изабелла отвечает ‘Indeed?’, затем «The Grail drew a long breath… she spoke»), но это вывод по соседству, а не улика; в списке говорящих её лучше держать как неатрибутированную реплику, а не молча приписывать Диор." + ] + } + ], + "круг1_сырой": { + "род": "not_applicable", + "первое_лицо": false, + "сверка": [ + { + "согласен": true, + "свой": null + }, + { + "согласен": false, + "свой": null + } + ] + } + }, + "f2274720c9": { + "род_голоса": "м", + "голос": "Gabriel (the Last Silversaint)", + "определим_по_окну": true, + "уверенность": "high", + "улики_голоса": [ + "eyes not on Celene now, but her brother", + "Gabriel brushed a lock of blood-slicked hair from his still-healing cheek, staring at the sevenstar on his palm. “I told her everything.”", + "The silversaint sighed.", + "The Last Silversaint looked up then, his one good eye alight. “I pity you, vampire,” he sighed." + ], + "говорящие": [], + "иноязычные_вставки_агентов": [ + "château", + "Jean-François" + ], + "латиница_законна": [], + "приёмы_агентов": [], + "приёмы": [], + "клаузы_повествования": [ + "I told her.", + "I told her everything.", + "I told her everything." + ], + "клаузы_речи": [], + "слои": "РАМКА (3 л.): авторская проза о допросе — «Jean-François sat with tome in lap», «Gabriel brushed a lock…», «The silversaint sighed», «Gabriel shrugged», «Jean-François scoffed», «The Last Silversaint looked up then» — плюс реплики самого хрониста в этом же слое («How did Lachance know?», «But she was being observed…», «The Pontifex's Palace», «Just like that?»). ВНУТРЕННИЙ РАССКАЗ (1 л., прош. вр.): всё, что в кавычках говорит Габриэль, — «I told her», «I told her everything», рассказ о Диор, Мэрин и хаосе в шато. ЦИТИРУЕМЫХ РЕПЛИК внутри рассказа Габриэля нет: он пересказывает события, но ничью прямую речь не цитирует, поэтому третий слой в этом окне пуст.", + "заметки": "Цепочка на род замкнута трижды и независимо: (1) хронист смотрит «not on Celene now, but her brother» — говорящий назван братом Селены; (2) абзац «Gabriel brushed a lock … from his still-healing cheek» непосредственно обрамляет реплику «I told her everything» — тот, кто говорит «я», описан через his; (3) прямая атрибуция «“I pity you, vampire,” he sighed». Поэтому voice_gender=male без догадок по имени.\n\nЧто НЕ попало в narration_clauses и почему: «come and speak to me» — глагол принадлежит Диор («First thing Dior did … was come and speak to me»), «мной» рода не метит; «stealing to my cell unseen» — притяжательное, «в мою камеру» рода не метит; «And she believed me» — сказуемое 3 л. ж. р. (Диор: «она поверила мне»), род рассказчика не выходит; «I pity you» и «Your kind lose something when you turn» — настоящее время, по условию исключены. Обе одинаковые клаузы «I told her everything» выписаны отдельно — это два разных места текста (до реплики про наблюдение и после «Gabriel shrugged»).\n\nДополнительно для замера: род Габриэля в русском будет вынужденно проступать и в РАМКЕ («brushed», «sighed», «shrugged», «looked up» → «смахнул», «вздохнул», «пожал», «поднял»), но это уже 3 л., а не голос внутреннего рассказа.\n\nТипографика: разрядки и капса целым словом в окне нет. Единственная особенность набора — пробел перед точкой в «Soldiers and servants everywhere .» (вероятно артефакт исходника, не приём), плюс непарные открывающие кавычки у абзацев внутреннего рассказа — окно выдрано из середины.\n\nФранцузское: «château» (дважды) — слово должно остаться шато, не «замком»; «Jean-François» — французская форма имени (Жан-Франсуа, с дефисом). Пограничные, не включённые: «Pontifex» (латынь), «San Maximille», «Esani», «silversaint» — авторские/вымышленные, не французские вставки как таковые.", + "адъюдикация": "", + "круг2_сверка": [ + { + "согласен": true, + "свой": "м", + "имя": "Gabriel (the Last Silversaint)", + "улика": "The frame is 3rd person around Jean-François (\"Jean-François sat with tome in lap, quill poised in his fingers, eyes not on Celene now, but her brother\"). Every \"I\" in the quoted inner narration belongs to Gabriel, fixed by adjacent attribution: \"'I told her.' Gabriel brushed a lock of blood-slicked hair from his still-healing cheek, staring at the sevenstar on his palm. 'I told her everything.'\" and \"Gabriel shrugged. 'I told her everything. Phoebe. Ashdrinker...'\". Gender closes on that same speaker three independent ways: he is Celene's *brother*; \"his still-healing cheek\"; \"The Last Silver", + "возражения": [] + }, + { + "согласен": true, + "свой": "м", + "имя": "Gabriel (the Last Silversaint)", + "улика": "Frame beats attribute the in-quotes first-person narration to Gabriel and mark him male four times over: \"eyes not on Celene now, but her brother\" (Jean-Francois directs \"How did Lachance know?\" at the brother, who answers \"I told her.\"); \"Gabriel brushed a lock of blood-slicked hair from HIS still-healing cheek, staring at the sevenstar on HIS palm. 'I told her everything.'\"; the same voice continues under \"The silversaint sighed.\" (still narrating about Dior); and \"The Last Silversaint looked up then, HIS one good eye alight. 'I pity you, vampire,' HE sighed.\" Narration clauses needing gende", + "возражения": [ + "Cosmetic only, not a refutation: the listed evidence item \"The silversaint sighed.\" carries no gender in English — it is an identity link in the attribution chain, not a gender marker. The actual male markers are \"her brother\", \"his still-healing cheek/his palm\", \"his one good eye\", \"he sighed\".", + "Cosmetic only: \"eyes not on Celene now, but her brother\" is not standalone evidence about the narrator — it only establishes whom the question is aimed at, and needs the following beat (\"Gabriel brushed... his cheek\") to close onto the speaker. The chain does close, so the conclusion stands." + ] + } + ], + "круг1_сырой": { + "род": "not_applicable", + "первое_лицо": false, + "сверка": [ + { + "согласен": true, + "свой": null + }, + { + "согласен": true, + "свой": null + } + ] + } + } +} \ No newline at end of file diff --git a/eval/dovodka/rol.py b/eval/dovodka/rol.py index be83003e..06fb8dc7 100644 --- a/eval/dovodka/rol.py +++ b/eval/dovodka/rol.py @@ -83,12 +83,29 @@ CORE = ZONE / "prompts" / "onepass-core.md" MAX_OUT = 32000 # как в заходе Д17: обрыв на потолке стоит денег и не даёт данных # ── ПАРА КАК ДАННЫЕ. Ни одна ветка ниже не спрашивает «а это китайский?» ────────────────────── +# ⛔⛔ МИНА ДВУХ ЭКЗЕМПЛЯРОВ КОНТУРА — ОБЕЗВРЕЖЕНА ЗДЕСЬ, А НЕ ОБЪЯВЛЕНА. Селфтест с 22.08 печатал +# предупреждение: в процессе живут ДВА независимых `contour` (свой у `rol` через `en_axis`, свой у +# `zakhod`), и `wire()` настраивал ТОЛЬКО первый — второй оставался на китайской паре. Тогда было +# записано «до данных не добралось». 23.08 добралось: скрипт, честно позвавший `PAIRS["en"]["wire"]()` +# и сразу спросивший текст БЕСПЛАТНОГО арма, получил ПУСТУЮ СТРОКУ — `free_text` идёт в контур +# ЗАХОДА, тот искал китайскую клетку английской главы, не нашёл и вернул пусто с одним warning'ом. +# В своде это выглядело бы как «у арма на этой главе мало дефектов»: пустой текст дефектов не имеет. +# ⇒ Пара включается в ОБОИХ экземплярах одной командой. Проверка селфтеста остаётся сторожем на +# случай третьего экземпляра. +_WIRE_OWN = {"zh": lambda: C.configure(PARA.ZH), "en": EN.wire} + + +def _wire(p: str) -> None: + _WIRE_OWN[p]() + ZK.PAIRS[p]["wire"]() + + PAIRS = { "zh": {"letter": "m", "phase": "ФД-M", "onepass": "A2", - "wire": lambda: C.configure(PARA.ZH), "units": lambda: C.units_ok(), + "wire": lambda: _wire("zh"), "units": lambda: C.units_ok(), "para": lambda: PARA.ZH}, "en": {"letter": "n", "phase": "ФД-N", "onepass": "E2", - "wire": EN.wire, "units": EN.units, "para": lambda: PARA.EN}, + "wire": lambda: _wire("en"), "units": EN.units, "para": lambda: PARA.EN}, } # ── ВОЗВРАТ АВТОРСКИХ АБЗАЦЕВ ИСХОДНИКУ ────────────────────────────────────────────────────── # ⚠⚠ ПОЧЕМУ ЭТО ОТДЕЛЬНЫЙ АРМ, А НЕ ПОЧИНКА ЭКСТРАКТОРА. Наш английский экстрактор @@ -444,6 +461,101 @@ def chosen(p: str) -> list[dict]: return ZK.chosen(p) +# ── АРМЫ ЧУЖИХ ФАЗ: клетки куплены ДРУГИМ РИГОМ, и схема клетки у них СВОЯ ──────────────────── +# ⛔ ПОЧЕМУ НЕ СТРОКА В `ARMS`. `ARMS` — реестр того, что покупает ЭТОТ риг: из него растут тег +# (`dv-n-…` на en), смета, гейт покупки и объявленный уровень размышления. `E6` ничем этим не +# является: его 16 клеток куплены `en_axis.py --e6` из кассы ФД-G, лежат под буквой ЧУЖОЙ фазы +# (`dv-g-e6-…`) и несут ДРУГИЕ поля — нет ни `pair`, ни `podacha`, ни `gen`, зато `role="editor3"`. +# Вписать его в `ARMS` значило бы объявить покупаемым то, что этот риг покупать не умеет и не должен. +# +# ⚠⚠ ЧЕМ ЭТО БЫЛО ОПАСНО ДО ПРАВКИ — И ЭТО РОВНО КЛАСС «РЕАЛИЗАЦИЯ НЕ ТО, ЧЕМ НАЗВАНА». Имя, не +# известное ни одному реестру, падало в последнюю ветку `read_texts` (`ZK.cell(ZK.tag(…))`), та +# строила `dv-j-e6-`, файла не находила и возвращала ПУСТУЮ СТРОКУ. А `emit_read` выбрасывает +# главу, у которой пуст хоть один арм. То есть команда `--panel=RG,E6,Z0,ZF` не упала бы и не +# соврала бы вслух — она собрала бы панель из СКОЛЬКИХ-ТО глав, и число это зависело бы от того, +# чьи файлы случайно нашлись. ⇒ ниже всё ГРОМКО: неизвестный арм — СТОП, негодная клетка — СТОП. +def _e6_wire(uid: str) -> tuple[list[dict], str, dict]: + """WIRE-АНАЛОГ `E6` — СОБСТВЕННЫМ КОДОМ ЕГО РИГА (`en_axis.cmd_e6`), не пере-написанным здесь. + + ⛔ Пере-написанный промт показал бы, что Я думаю о клетке, а не что ушло в модель, — то есть + ровно тот самый класс, против которого гейт `--wire` и заведён. Поэтому вызываются те же + функции в том же порядке: исходник и черновик берутся у `en_axis`, сообщения собирает боевой + `PR.editor_msgs` пары en, тело вызова строит РОСТЕР НАПРЯМУЮ (`ROSTER.call_kwargs`), а не + `rol.call_kwargs` — у `E6` иной потолок вывода, и подменять его нашим значило бы напечатать + не тот провод (класс В7: несущий контраст, собранный под разными потолками). + """ + src = next(u["source"] for u in EN.units() if u["uid"] == uid) + msgs = C.PR.editor_msgs(src, EN.base_draft(uid), EN._law(src), pair="en-ru") # noqa: SLF001 + return msgs, EN.EDITOR2, ROSTER.call_kwargs(EN.EDITOR2, msgs) + + +FOREIGN = { + "E6": {"pair": "en", "prefix": "dv-g-e6-", "model": "glm-5", "role": "editor3", + "phase": "ФД-G", "rig": "eval/dovodka/en_axis.py --e6", "wire": _e6_wire, + "что": "ВТОРОЙ редактор glm-5 поверх боевого черновика D0 (носитель гипотезы H-4)"}, +} + + +def foreign_defect(d: dict, arm: str, uid: str) -> str: + """Почему клетка чужой фазы НЕ годится в панель. Пусто = годна. + + ⚠ Проверки идут по СОДЕРЖИМОМУ клетки, а не по имени файла: имя мы строим сами, и оно не + удостоверяет ничего. Клетка обязана сама сказать, чей она арм, какой главы, какой модели и + какой роли, — иначе под именем `E6` в панель уедет что угодно, что лежит по этому пути. + ⚠ Функция ЧИСТАЯ (dict → строка) намеренно: только так селфтест может уронить её на заведомо + больном входе, не подкладывая порченых файлов в `~/books`. + """ + spec = FOREIGN[arm] + got_model = d.get("model_returned") or d.get("model") + for what, got, want in (("arm", d.get("arm"), arm), ("uid", d.get("uid"), uid), + ("role", d.get("role"), spec["role"]), + ("модель", got_model, spec["model"])): + if got != want: + return f"поле {what}={got!r}, ожидалось {want!r}" + if d.get("finish") != "stop": + return f"finish={d.get('finish')!r} — клетка оборвана либо мертва" + if not (d.get("content") or "").strip(): + return "content пуст при finish=stop — деньги списаны, текста нет (класс В5)" + return "" + + +def foreign_text(p: str, arm: str, uid: str) -> str: + """Текст арма чужой фазы. Любая беда — СТОП, а НЕ пустая строка: молча выброшенная глава + меняет состав панели, объявленный пре-регом, и делает это невидимо.""" + spec = FOREIGN[arm] + if spec["pair"] != p: + raise SystemExit(f"⛔ арм {arm} существует только на паре «{spec['pair']}», запрошена «{p}»" + f" — его клетки купил {spec['rig']} из кассы {spec['phase']}") + f = OUT / f"{spec['prefix']}{uid}.json" + if not f.exists(): + raise SystemExit(f"⛔ клетки {arm} для главы {uid} нет на диске ({f.name}). Этот риг её " + f"купить не может — она из кассы {spec['phase']}, риг {spec['rig']}") + d = json.loads(f.read_text(encoding="utf-8")) + why = foreign_defect(d, arm, uid) + if why: + raise SystemExit(f"⛔ клетка {arm}/{uid} НЕГОДНА: {why}") + return d["content"] + + +def arm_text(p: str, arm: str, uid: str) -> str: + """ОДНА точка правды о том, откуда берётся текст арма. Неизвестное имя — СТОП. + + ⚠ Прежде неизвестное имя молча уходило в риг захода и возвращало пусто (см. блок выше). Теперь + реестры перечислены явно, и опечатка в `--panel=` роняет сборку, а не режет панель. + """ + if arm in FOREIGN: + return foreign_text(p, arm, uid) + if arm in FREE: + return free_text(p, arm, uid) + if arm in ARMS: + return cell(tag(p, arm, uid)) + if arm in ZK.ARMS: + return ZK.cell(ZK.tag(p, arm, uid)) + raise SystemExit(f"⛔ арм {arm!r} не известен НИ ОДНОМУ реестру: бесплатные {FREE}, " + f"покупаемые этим ригом {tuple(ARMS)}, армы захода {ZK.ARMS}, " + f"чужих фаз {tuple(FOREIGN)}. Панель НЕ собирается") + + # ⛔⛔ БЛОКЕРЫ Б6/Б7 РЕВЬЮ 21.08. Ростер кодирует ОДНИМ режимом `none` («ручку не шлём») две # ПРОТИВОПОЛОЖНЫЕ вещи: у `deepseek-v4-pro` вендор-дефолт — размышление HIGH, у `grok-4.3` — LOW # (квирк-бюллетень :60/:80). Значит «одинаковая конфигурация по ростеру» означает РАЗНОЕ @@ -817,6 +929,40 @@ def cmd_selftest() -> int: else: ok, d = True, "" ck(f"Б6 {a}: на провод уходит объявленный уровень «{lvl}»", ok, d) + + # ── ШАГ 1 п.0 ПЛАНА 22.08: АРМЫ ЧУЖИХ ФАЗ (`E6`) ──────────────────────────────────────── + # ⚠ ГЕЙТ ПРОВЕРЯЕТСЯ НА ЗАВЕДОМО БОЛЬНОМ ВХОДЕ. «Зелено на здоровом» не сторожит ничего — + # ровно так селфтест Б8 был зелен вхолостую на арме, у которого файлов не было вовсе. Больной + # вход делается МУТАЦИЕЙ НАСТОЯЩЕЙ клетки, чтобы проверка не разъехалась с реальной схемой. + for fa, spec in FOREIGN.items(): + pp = spec["pair"] + PAIRS[pp]["wire"]() + us = chosen(pp) + have = [u["uid"] for u in us if (OUT / f"{spec['prefix']}{u['uid']}.json").exists()] + ck(f"{fa}: клетка есть на КАЖДОЙ главе пары {pp}", len(have) == len(us), + f"{len(have)} из {len(us)}") + if not have: + continue + fu = have[0] + real = json.loads((OUT / f"{spec['prefix']}{fu}.json").read_text(encoding="utf-8")) + ck(f"{fa}: настоящая клетка гейт ПРОХОДИТ", not foreign_defect(real, fa, fu), + foreign_defect(real, fa, fu)) + for name, patch in (("чужой арм", {"arm": "RG"}), ("чужая глава", {"uid": "0" * 10}), + ("чужая роль", {"role": "onepass"}), + ("чужая модель", {"model_returned": "grok-4.3"}), + ("обрыв finish=length", {"finish": "length"}), + ("пустой content", {"content": " "})): + ck(f"{fa}: гейт РОНЯЕТ больной вход «{name}»", + bool(foreign_defect(dict(real, **patch), fa, fu))) + other = next((x for x in PAIRS if x != pp), pp) + for name, fn in ((f"{fa} на чужой паре {other}", lambda: foreign_text(other, fa, fu)), + ("неизвестное имя арма", lambda: arm_text(pp, "ZZZ", fu))): + try: + fn() + ck(f"{fa}: {name} — это СТОП", False, "вернулось молча, без исключения") + except SystemExit: + ck(f"{fa}: {name} — это СТОП", True) + print(f"\n{'ЗАМЕР ГОДЕН К ПОКУПКЕ' if not bad else f'ПРОВАЛОВ: {bad}'}") return bad @@ -880,9 +1026,7 @@ def read_texts(p: str, uid: str) -> dict: """Тексты панели чтения. Пусто у любого арма — глава в пакет не идёт целиком.""" out = {"_src": next(u["source"] for u in chosen(p) if u["uid"] == uid)} for a in READ_PANEL: - t = free_text(p, a, uid) if a in FREE else ( - cell(tag(p, a, uid)) if a in ARMS else ZK.cell(ZK.tag(p, a, uid))) - out[a] = t + out[a] = arm_text(p, a, uid) return out @@ -1027,14 +1171,19 @@ def wire_dump(p: str, only: str = "") -> int: ("Z7 канон-фиксер", C.fix_msgs(src, d, ["КАНОН: термин X"]), ARMS_MODEL["Z0"]), ("ZP однопроходка-склейка", C.a2_msgs(src), ARMS_MODEL["Z0"])] cases += [(f"{a} однопроходка-роль", rol_msgs(p, src, a), ARMS[a][0]) for a in ARMS] + # ⚠ Армы чужих фаз печатаются ТЕМ ЖЕ гейтом и рядом с остальными: панель их смешивает, значит + # и читать их провод надо в одном месте. Тело вызова у них СВОЁ — см. `_e6_wire`. + cases = [(n, m, mo, None) for n, m, mo in cases] + cases += [(f"{fa} {sp['что']} · касса {sp['phase']}", *sp["wire"](u["uid"])) + for fa, sp in FOREIGN.items() if sp["pair"] == p] base = None - for name, msgs, model in cases: + for name, msgs, model, own_kw in cases: arm = name.split()[0] if only and only != arm: continue sysm = "\n\n".join(x["content"] for x in msgs if x["role"] == "system") base = base or len(sysm) - kw = call_kwargs(model, msgs, arm) + kw = own_kw if own_kw is not None else call_kwargs(model, msgs, arm) print("\n" + "=" * 100) print(f"АРМ {name} · модель {model} · размышление: {THINK_LEVEL.get(arm, 'как у ростера')}") print(f"инструкции {len(sysm)} знаков (×{len(sysm) / base:.2f} к первому арму) · " diff --git a/eval/dovodka/schet.py b/eval/dovodka/schet.py new file mode 100644 index 00000000..712fe13d --- /dev/null +++ b/eval/dovodka/schet.py @@ -0,0 +1,524 @@ +#!/usr/bin/env python3 +"""СЧЁТЧИКИ ДЕФЕКТ-КЛАССОВ — первичный прибор панели-0. $0, детерминированно. + +⚠ ЗАЧЕМ ОТДЕЛЬНЫЙ ПРИБОР, КОГДА ЕСТЬ СЛЕПОЕ ЧТЕНИЕ. Ранговый прибор при наших размерах безнадёжен: +эффект в ОДНО место стоит 40 глав Гу на китайской паре и 68 на английской (мощностная таблица +консилиума 22.08). Панель-0 — 7.8 главы Гу, её MDE ≈ 2 места. ⇒ ранговый эндпойнт этой панели +объявлен ОПИСАТЕЛЬНЫМ ЗАРАНЕЕ, а несущим становится СЧЁТНЫЙ: дефект-класс, ломающийся в 20–30% +глав при ~0 у компаратора, ловится уже на 25–30 единицах. + +⚠ И ЭТО ЖЕ ДОЛГ ШАГА 5.2 ПЛАНА. Покупать 15 глав Гу под вопрос о кросс-главной консистентности, +не имея счётчиков, значит повторить класс В20 ревью — оплаченные клетки, которых не прочёл ни один +прибор. Счётчики отлаживаются ЗДЕСЬ, на уже купленном, и только потом едут в дорогой замер. + +ЧТО СЧИТАЕТСЯ (четыре класса, объявлены ДО снятия — пре-рег Д32.0): + + род формы 1 л. ед. ч. прош. вр. с неверным родом. ТРИ непересекающихся подкласса: + «эталон» — пол голоса внутреннего рассказа по окну УСТАНОВЛЕН, форма ему противоречит; + «разнобой» — пол по окну НЕ устанавливается, но арм ставит в одном слое ОБА рода + (источник-независимый дефект: винить за выбор нельзя, за два сразу можно); + «речь» — род, не принадлежащий ни одному объявленному цитируемому говорящему + язык непереведённый кусок исходного языка (латиница), КРОМЕ римских цифр и вставной + французской РЕПЛИКИ (её и только её боевой пар-мандат велит оставить чужой; имена, + топонимы и «шато/мадемуазель» он велит передавать кириллицей — латиница на их месте + есть тот самый дефект). На всю панель такая реплика ОДНА: «A farmer's son, oui.» + приём авторский типографский приём исходника (разрядка «P A T I E N C E»), ПОТЕРЯННЫЙ выходом + банк термины банка, чья канонная форма в выходе встречается реже, чем в исходнике + +⛔⛔ ЭТАЛОН СНЯТ ПО ИСХОДНИКУ И СЛЕПО К ПЕРЕВОДАМ, И ИНАЧЕ ОН НЕ СТОИТ НИЧЕГО. Требование п.3а +плана: «эталон грепов фиксируется ДО снятия, иначе их можно подогнать под увиденное». Исполнено +буквально: каждую главу читали три независимых агента (строитель + два скептика, один из них с +мандатом ОПРОВЕРГНУТЬ), которым был открыт РОВНО ОДИН файл — английский исходник главы; русские +переводы, код зоны и отчёт им были закрыты. Расхождения разрешены руками и названы в отчёте +поимённо. Эталон лежит рядом файлом и фризится своим коммитом ДО сборки пакетов. + +⚠⚠ ПЕРВЫЙ КРУГ ЭТАЛОНА БЫЛ НЕГОДЕН, И ЭТО ПОЙМАЛА ЕГО ЖЕ СВЕРКА. Вопрос был задан про «пол +рассказчика», а книга РАМОЧНАЯ: хронист пишет в третьем лице, а рассказ героя идёт от первого +лица внутри кавычек. Половина строителей сочла внутренний рассказ «прямой речью» и объявила +первое лицо отсутствующим — на восьми главах из шестнадцати. Круг переспрошен с НАЗВАННОЙ рамкой; +переводы агентам оставались закрыты в обоих кругах, то есть исправлена постановка вопроса, а не +подогнан ответ. Оба круга лежат в эталоне, расхождение видно. + +⚠ ПРИБОР ПЕЧАТАЕТ СТРОКИ, А НЕ ТОЛЬКО ЧИСЛА (требование п.3а). Счёт без улик не проверяем никем, +включая меня: ровно так «13 катастроф» эксп-13 оказались пятью-шестью при оверфлаге судьи. + +⚠ ЧЕГО ПРИБОР НЕ УМЕЕТ, И ЭТО ОБЪЯВЛЕНО ДО ЗАМЕРА: + · рассказчик 1-го лица без имени лукапу по банку недоступен — род берётся из эталона главы, + а не из банка (полей пола в `bank-en.json` нет вовсе, см. Шаг 7 плана); + · разделение «повествование против прямой речи» механическое (см. `_speech_spans`) и у разных + армов может лечь по-разному — поэтому классификация КАЖДОГО попадания печатается, а число + попаданий, сменивших класс между армами, выносится в свод отдельной строкой; + · класс «приём» на этой панели применим к ОДНОЙ главе из шестнадцати — это анекдот, а не класс, + и он объявляется описательным до того, как будет посчитан. + +Запуск: schet.py --selftest гейты прибора, включая ФАЛЬСИФИКАЦИЮ на подсаженном браке + schet.py --report [армы…] таблица по главам и агрегат со знаковым тестом + schet.py --hits <АРМ> [uid] все попадания с контекстом — для чтения глазами +""" +from __future__ import annotations + +import importlib.util +import json +import re +import sys +from pathlib import Path + +REPO = Path("/home/ubuntu/projects/textmachine") +ZONE = Path(__file__).resolve().parent +for d in ("dovodka", "editor_tier", "tenant_panel", "role_topology", "bank_arbitration"): + sys.path.insert(0, str(REPO / "eval" / d)) + + +def _load(name: str, path: Path): + spec = importlib.util.spec_from_file_location(name, path) + mod = importlib.util.module_from_spec(spec) + sys.modules[name] = mod + spec.loader.exec_module(mod) + return mod + + +# ⚠ Тексты армов берутся У `rol`, а не читаются заново: там уже стоят реестры источников и гейт +# годности клетки чужой фазы. Второй загрузчик разъехался бы с ним молча. +R = _load("rol_schet", ZONE / "rol.py") +ZS = _load("zsud_schet", ZONE / "zsud.py") # знаковый тест — один на зону, не второй + +ETALON = ZONE / "etalon-panel0.json" +PAIR = "en" +PANEL = ("ZD", "Z0", "ZF", "RG", "E6") + +# ── КЛАСС «РОД» ────────────────────────────────────────────────────────────────────────────── +# ⚠ ОТБОР ФОРМ УЖЕСТОЧЁН ПОСЛЕ ПРОВЕРКИ ИСПОЛНЕНИЕМ, И ПЕРВАЯ РЕДАКЦИЯ БЫЛА НЕГОДНОЙ. Она брала +# любую форму на -л/-ла, у которой в окне ±40 знаков стояло «я», — и считала третьи лица +# («Габриэль пожал плечами») и СУЩЕСТВИТЕЛЬНЫЕ на -л («Пьющий пепел»). На главе `f2274720c9` она +# давала 2ж/5м там, где настоящих форм 1 л. три и все мужские. ⇒ местоимение обязано стоять в +# синтаксической связи: сразу перед глаголом (через 0–3 служебных слова) или сразу после него. +_ADV = (r"(?:не|уже|бы|тоже|также|всё|ещё|лишь|только|чуть|едва|снова|вновь|даже|так|там|тут|" + r"потом|тогда|сразу|вдруг|наконец|почти|словно|будто|нехотя|молча|тихо|быстро)\s+") +_FORM = r"[а-яё]+л(?:ась|ся|а)?" +_RE_ROD = (re.compile(rf"\bя\s+(?:{_ADV}){{0,3}}({_FORM})\b", re.I), + re.compile(rf"\b({_FORM})\s+(?:{_ADV}){{0,1}}я\b", re.I)) +_FEM = ("ла", "лась") + +# ── КЛАСС «ЯЗЫК» ───────────────────────────────────────────────────────────────────────────── +_RE_LAT = re.compile(r"[A-Za-z][A-Za-z'’\-]+") +# ⚠ Римская цифра — НЕ кусок исходного языка: «Людовик VIII» законен в русской прозе и стоит во +# всех армах одинаково. Считать её браком значило бы вписать в счётчик константу шума. +_RE_ROMAN = re.compile(r"^[IVXLCDM]+$") +# ⛔ ЛАТИНИЦА В РАЗРЯДКУ — ОТДЕЛЬНЫЙ ДЕТЕКТОР, И ЕГО НЕ БЫЛО. Первая редакция `_RE_LAT` требовала +# от слова ДВУХ букв подряд, а `P A T I E N C E` — восемь одиночных букв через пробел: класс «язык» +# был к ней слеп по построению. Поймано чтением улик: `RG` единственный сохранил авторскую разрядку +# главы `197f98eb61` — и сохранил её ПО-АНГЛИЙСКИ, то есть приём удержал, а слово не перевёл. +# Без этого детектора свод печатал бы «приём цел, языка нет» и хвалил бы арм за непереведённое слово. +_RE_LAT_SP = re.compile(r"(?:(?<=\s)|^)(?:[A-Za-z]\s){2,}[A-Za-z](?=[\s.,!?:;—»]|$)") + +# ── КЛАСС «ПРИЁМ» ──────────────────────────────────────────────────────────────────────────── +# Разрядка: три и более одиночных буквы через пробел. Ищется В ВЫХОДЕ по факту наличия ЛЮБОЙ +# разрядки, а не по совпадению букв: русское слово другое, приём тот же. +_RE_SPACED = re.compile(r"(?:(?<=\s)|^)(?:[A-Za-zА-Яа-яЁё]\s){2,}[A-Za-zА-Яа-яЁё](?=[\s.,!?:;—]|$)") + + +def etalon() -> dict: + if not ETALON.exists(): + raise SystemExit(f"⛔ эталона нет ({ETALON.name}). Он снимается ПО ИСХОДНИКУ и ДО замера — " + "снять его после того, как счётчик показал числа, значит подогнать") + return json.loads(ETALON.read_text(encoding="utf-8")) + + +def _paras(t: str) -> list[tuple[int, str]]: + """(смещение, абзац). Абзац — строка: русская вёрстка реплик поабзацная.""" + out, pos = [], 0 + for line in t.split("\n"): + if line.strip(): + out.append((pos, line)) + pos += len(line) + 1 + return out + + +def _speech_spans(t: str) -> list[tuple[int, int]]: + """Куски текста, лежащие в ПРЯМОЙ РЕЧИ, а не в повествовании. + + ⚠ Правило механическое и объявлено ДО замера: абзац-реплика начинается с тире; каждое + «закрывающее» тире (`, — `, `. — `, `? — `, `! — `, `… — `) ПЕРЕКЛЮЧАЕТ слой. Куски чётные — + речь, нечётные — слова автора, то есть повествование. Нет ни одного тире — речью считается + весь абзац. + + ⛔⛔ ПЕРВАЯ РЕДАКЦИЯ БЫЛА НЕГОДНОЙ, И ПОЙМАЛО ЕЁ ЧТЕНИЕ УЛИК ГЛАЗАМИ, А НЕ ГЕЙТ. Она обрывала + речь на ПЕРВОМ тире и всё дальнейшее звала повествованием — то есть не знала ВОЗОБНОВЛЕНИЯ + реплики, а русская вёрстка диалога именно чередуется: «— речь, — слова автора. — речь». Цена + ошибки замерена: на главе `49ca859c94` реплика Жан-Франсуа «…как и я, мадемуазель Кастия. Нет, + я сбежал в Огюстен…» ложилась в ПОВЕСТВОВАНИЕ, и мужская форма мужского говорящего шла в + дефекты рассказчицы — у ВСЕХ ТРЁХ армов сразу. Это класс «прибор производит брак вместо того, + чтобы его находить»; общий знаменатель парного контраста не портил, но абсолютные числа врал. + """ + out = [] + for pos, line in _paras(t): + s = line.lstrip() + if not s.startswith(("—", "–", "-")): + continue + head = pos + (len(line) - len(s)) + cuts = [m.start() + 1 for m in re.finditer(r"[,.!?…»]\s*[—–]\s", s)] + b = [0, *cuts, len(s)] + out += [(head + b[k], head + b[k + 1]) for k in range(len(b) - 1) if k % 2 == 0] + return out + + +def rod_hits(text: str) -> list[dict]: + """Все формы 1 л. ед. ч. прош. вр. с родом, местом и классом «речь/повествование».""" + sp = _speech_spans(text) + seen, out = set(), [] + for rx in _RE_ROD: + for m in rx.finditer(text): + i = m.start(1) + if i in seen: + continue + seen.add(i) + w = m.group(1).lower() + lo, hi = max(0, i - 60), min(len(text), m.end(1) + 30) + out.append({"i": i, "слово": w, + "род": "ж" if w.endswith(_FEM) else "м", + "речь": any(a <= i < b for a, b in sp), + "ктx": text[lo:hi].replace("\n", " ")}) + return sorted(out, key=lambda x: x["i"]) + + +def rod_defects(text: str, et: dict) -> list[dict]: + """Попадания, чей род ЭТАЛОНУ ПРОТИВОРЕЧИТ. Два ПОДКЛАССА, и они не пересекаются. + + ⚠⚠ ПОДКЛАСС «ЭТАЛОН» работает там, где пол голоса внутреннего рассказа ПО ОКНУ УСТАНОВЛЕН. + Тогда каждая форма слоя повествования обязана нести именно его. Это сильная проверка. + + ⚠⚠ ПОДКЛАСС «РАЗНОБОЙ» работает там, где пол по окну НЕ устанавливается, — и он ИСТОЧНИК- + НЕЗАВИСИМ. Окно в 1600 знаков часто не даёт улики вовсе; арм видел ровно то же окно и большего + знать не мог, поэтому винить его за выбор рода нельзя. Но нельзя и не винить за ДВА рода + сразу в одном слое одной главы: это ошибка внутренняя, для неё исходника не требуется. Ровно + её владелец увидел сам («дрейф пола Рейн между отрывками, у всех четырёх армов») и пометил + как то, «что счётчик не увидит». Теперь увидит. + + ⚠ ПРЯМАЯ РЕЧЬ проверяется СЛАБО и это объявляется: говорящих несколько, дефектом считается + только род, не принадлежащий НИ ОДНОМУ объявленному говорящему. А если хоть у одного из них + пол по окну не устанавливается, речь не проверяется ВОВСЕ — иначе законная форма неизвестного + говорящего пошла бы в дефекты, и счётчик стал бы производить брак вместо того, чтобы его + находить. + """ + voice = et.get("род_голоса") + speakers = et.get("говорящие", []) + allowed = ({voice} | {s.get("род") for s in speakers}) - {None, "unknown"} + # ⛔ РЕЧЬ НЕ ПРОВЕРЯЕТСЯ, ЕСЛИ ХОТЬ ОДИН ГОВОРЯЩИЙ ГЛАВЫ НЕ ИМЕЕТ ОБЪЯВЛЕННОГО ПОЛА — включая + # САМОГО РАССКАЗЧИКА. Первая редакция этого не делала, и вот что выходило: на главе + # `5a8f48d24a` пол голоса по окну не устанавливается, в списке остались только Персиваль и + # Вульфрик (оба «м»), и собственная реплика рассказчицы «— Где я была?» шла в дефекты как + # «род ж не принадлежит ни одному говорящему главы». Прибор ловил не арм, а сам себя. + speech_blind = voice in (None, "unknown") or any( + s.get("род") in (None, "unknown") for s in speakers) + bad, narr = [], [] + for h in rod_hits(text): + if h["речь"]: + if allowed and not speech_blind and h["род"] not in allowed: + bad.append(dict(h, подкласс="речь", + почему=f"род {h['род']} не принадлежит ни одному говорящему главы " + f"{sorted(allowed)}")) + continue + narr.append(h) + if voice in ("ж", "м") and h["род"] != voice: + bad.append(dict(h, подкласс="эталон", + почему=f"повествование: голос рассказа {voice}, форма {h['род']}")) + if voice not in ("ж", "м") and len({h["род"] for h in narr}) > 1: + # ⚠ Дефектом считается МЕНЬШИНСТВО форм, а не все: разнобой из 3ж+1м есть одна ошибка, + # а не четыре, и мерить его надо так же, как подкласс «эталон», иначе агрегат перекосит. + few = min({"ж", "м"}, key=lambda g: sum(1 for h in narr if h["род"] == g)) + for h in narr: + if h["род"] == few: + bad.append(dict(h, подкласс="разнобой", + почему="в слое повествования одной главы стоят ОБА рода; пол по " + "окну не устанавливается, поэтому дефект — меньшинство форм")) + return bad + + +def lang_defects(text: str, et: dict) -> list[dict]: + """Куски исходного языка. Законные иноязычные вставки эталона и римские цифры не в счёт.""" + # ⚠ БЕЛЫЙ СПИСОК — НЕ «всё французское», а РОВНО вставная реплика. Основание — боевой + # пар-мандат `en-ru/translator.md`, секция ФРАНЦУЗСКИЙ СЛОЙ: имена и топонимы ТРАНСКРИБИРУЮТСЯ, + # мадемуазель/месье/шато идут РУССКОЙ традицией галлицизмов, и чужими остаются только вставные + # французские РЕПЛИКИ. Значит `château` или `Capitaine` латиницей в русском выходе есть тот + # самый дефект, который класс ловит, а не законная вставка. + ok = {w.lower() for ins in et.get("латиница_законна", []) for w in _RE_LAT.findall(ins)} + out, taken = [], [] + for m in _RE_LAT_SP.finditer(text): + w = m.group(0) + flat = w.replace(" ", "") + taken.append((m.start(), m.end())) + if flat.lower() in ok or _RE_ROMAN.match(flat): + continue + lo, hi = max(0, m.start() - 45), min(len(text), m.end() + 25) + out.append({"i": m.start(), "слово": w, "ктx": text[lo:hi].replace("\n", " "), + "почему": "латиница В РАЗРЯДКУ: авторский приём удержан, слово НЕ переведено"}) + for m in _RE_LAT.finditer(text): + w = m.group(0) + if w.lower() in ok or _RE_ROMAN.match(w) or any(a <= m.start() < b for a, b in taken): + continue + lo, hi = max(0, m.start() - 45), min(len(text), m.end() + 25) + out.append({"i": m.start(), "слово": w, "ктx": text[lo:hi].replace("\n", " "), + "почему": "латиница вне вставной французской реплики"}) + return sorted(out, key=lambda x: x["i"]) + + +def priem_defects(text: str, et: dict) -> list[dict]: + """Авторский типографский приём исходника, которого в выходе НЕТ.""" + if not et.get("приёмы"): + return [] + if _RE_SPACED.search(text): + return [] + return [{"i": -1, "слово": "", "ктx": "; ".join(x["текст"] for x in et["приёмы"]), + "почему": "разрядка исходника в выходе отсутствует"}] + + +def bank_defects(src: str, text: str) -> list[dict]: + return [{"i": -1, "слово": g, "ктx": "", "почему": "канонная форма банка не доехала"} + for g in R.C.canon_gaps(src, text)] + + +CLASSES = ("род", "язык", "приём", "банк") + + +def defects(src: str, text: str, et: dict) -> dict: + return {"род": rod_defects(text, et), "язык": lang_defects(text, et), + "приём": priem_defects(text, et), "банк": bank_defects(src, text)} + + +# ── СВОД ───────────────────────────────────────────────────────────────────────────────────── +def collect(arms: tuple = PANEL) -> tuple[list, dict]: + et_all = etalon() + R.PAIRS[PAIR]["wire"]() + us, data, empty = [], {}, [] + for u in R.chosen(PAIR): + if u["uid"] not in et_all: + continue + tx = {a: R.arm_text(PAIR, a, u["uid"]) for a in arms} + # ⛔ ГЛАВА С ПУСТЫМ ТЕКСТОМ ХОТЬ У ОДНОГО АРМА ИЗ СЧЁТА ВЫБРАСЫВАЕТСЯ, И ВСЛУХ. Пустой текст + # дефектов не имеет по построению, то есть арм с пропавшей клеткой выглядел бы ЛУЧШИМ. + # Ровно так мина двух контуров чуть не подарила черновику «чистую» главу (см. rol._wire). + if not all(tx[a].strip() for a in arms): + empty.append((u["uid"], [a for a in arms if not tx[a].strip()])) + continue + us.append(u) + for a in arms: + data[(u["uid"], a)] = defects(u["source"], tx[a], et_all[u["uid"]]) + if empty: + print(f" ⛔ ГЛАВ ВЫБРОШЕНО ИЗ СЧЁТА (пустой текст у арма): {len(empty)}") + for uid, aa in empty: + print(f" {uid}: пусто у {aa}") + return us, data + + +def report(arms: tuple = PANEL) -> int: + et_all = etalon() + us, data = collect(arms) + print(f"\n=== СЧЁТНЫЙ ПРИБОР ПАНЕЛИ-0 · пара {PAIR} · глав {len(us)} · армы {' '.join(arms)} ===") + print("⚠ первичная величина — ЧИСЛО ГЛАВ С ≥1 ФАТАЛОМ (агрегат по четырём классам);\n" + " по-классовые разбивки вторичны; ранги этой панели объявлены ОПИСАТЕЛЬНЫМИ заранее\n") + for cl in CLASSES: + print(f" {'глава':12s}" + "".join(f"{a:>6s}" for a in arms) + f" класс «{cl}»") + for u in us: + row = [len(data[(u["uid"], a)][cl]) for a in arms] + mark = "" if len(set(row)) == 1 else " ←" + print(f" {u['uid']:12s}" + "".join(f"{x:6d}" for x in row) + mark) + print(f" {'ИТОГО':12s}" + + "".join(f"{sum(len(data[(u['uid'], a)][cl]) for u in us):6d}" for a in arms) + "\n") + print(f" {'глава':12s}" + "".join(f"{a:>6s}" for a in arms) + " ВСЕ КЛАССЫ (фаталов)") + tot = {a: 0 for a in arms} + chap = {a: 0 for a in arms} + for u in us: + row = [] + for a in arms: + n = sum(len(data[(u["uid"], a)][c]) for c in CLASSES) + tot[a] += n + chap[a] += n > 0 + row.append(n) + print(f" {u['uid']:12s}" + "".join(f"{x:6d}" for x in row)) + print(f" {'фаталов':12s}" + "".join(f"{tot[a]:6d}" for a in arms)) + print(f" {'глав с ≥1':12s}" + "".join(f"{chap[a]:6d}" for a in arms) + f" из {len(us)}") + # ⚠ Сколько попаданий сменило класс «речь/повествование» между армами — цена механического + # правила. Печатается всегда, а не только когда мала. + moved = 0 + for u in us: + cls = [{h["слово"]: h["речь"] for h in rod_hits(R.arm_text(PAIR, a, u["uid"]))} + for a in arms] + keys = set().union(*cls) + moved += sum(1 for k in keys if len({c[k] for c in cls if k in c}) > 1) + print(f"\n ⚠ попаданий, сменивших класс «речь/повествование» между армами: {moved}") + + def _test(title: str, val) -> None: + print(f"\n {title}") + for i, a in enumerate(arms): + for b in arms[i + 1:]: + d = [val(u["uid"], a) - val(u["uid"], b) for u in us] + nz = [x for x in d if x] + p = ZS._sign_p(d) # noqa: SLF001 + print(f" {a} − {b}: сумма {sum(d):+4d} · глав с разницей {len(nz):2d} " + f"(в пользу {b}: {sum(1 for x in nz if x > 0)}) · p={p:.4f}" + f"{' РАЗЛИЧИМО' if p < 0.05 else ''}") + + def _all(uid: str, a: str) -> int: + return sum(len(data[(uid, a)][c]) for c in CLASSES) + + # ⛔ ПЕРВИЧНОЕ ПРАВИЛО ПЕЧАТАЕТСЯ ПЕРВЫМ И ПЕЧАТАЕТСЯ ВСЕГДА, каким бы ни вышло. Оно объявлено + # п.3б плана ДО чисел: величина — БИНАРНАЯ «есть ли в главе хоть один фатал», тест — парный + # знаковый. Подменить его на счётный, увидев, что счётный красивее, значит подогнать правило + # под результат; счётный идёт НИЖЕ и назван вторичным, как и объявлено. + _test("① ПЕРВИЧНОЕ ПРАВИЛО п.3б — бинарно «глава с ≥1 фаталом», парный знаковый:", + lambda uid, a: int(_all(uid, a) > 0)) + _test("② вторичное — ЧИСЛО фаталов на главу:", _all) + for cl in CLASSES: + _test(f"③ вторичное, по классу «{cl}»:", lambda uid, a, c=cl: len(data[(uid, a)][c])) + + # ── ЧАСТОТА С ИНТЕРВАЛОМ, А НЕ ВЕРДИКТ ────────────────────────────────────────────────── + # ⛔ Требование плана 22.08 §4: «редкий класс (ломается в ~10% глав) при 15 главах Гу НЕ + # РАЗРЕШАЕТСЯ — по редким печатать ЧАСТОТУ С ИНТЕРВАЛОМ, а не вердикт». Здесь оно и исполняется. + # ⚠ И печатается ПОТОЛОК МОЩНОСТИ знакового теста: при всех расхождениях в одну сторону + # двусторонний p = 2/2^k, то есть p<0.05 недостижим, пока глав с ненулевой разницей меньше + # шести. Класс, который ломается на трёх главах из шестнадцати, эта панель не разрешит НИКОГДА, + # как бы односторонен ни был результат. Число печатается, чтобы «не различимо» не читалось как + # «одинаково». + k = 1 + while 2 / 2 ** k >= 0.05: + k += 1 + print(f"\n ④ ЧАСТОТА ГЛАВ С ДЕФЕКТОМ (доля из {len(us)}) и 95% интервал Уилсона.") + print(f" ⚠ потолок мощности: знаковый тест даёт p<0.05 не раньше, чем на {k} главах с " + f"ненулевой разницей, ВСЕ в одну сторону (2/2^{k} = {2 / 2 ** k:.4f}).") + print(f" {'класс':8s}" + "".join(f"{a:>22s}" for a in arms)) + for cl in (*CLASSES, "ВСЕ"): + line = f" {cl:8s}" + for a in arms: + n = len(us) + x = sum(1 for u in us if (len(data[(u["uid"], a)][cl]) if cl != "ВСЕ" + else _all(u["uid"], a)) > 0) + ph, z = x / n, 1.96 + den = 1 + z * z / n + c = (ph + z * z / (2 * n)) / den + hw = z * ((ph * (1 - ph) / n + z * z / (4 * n * n)) ** 0.5) / den + line += f"{f'{x}/{n} [{max(0, c - hw):.2f};{min(1, c + hw):.2f}]':>22s}" + print(line) + print(f"\n ⚠ ПОПАДАНИЙ ВСЕГО (не глав) — описательно, парности не имеет:") + for cl in CLASSES: + print(f" {cl:8s}" + "".join( + f"{sum(len(data[(u['uid'], a)][cl]) for u in us):>22d}" for a in arms)) + print(f"\n эталон: {ETALON.name} · глав в эталоне {len(et_all)}") + return 0 + + +def hits(arm: str, uid: str = "") -> int: + """Все попадания с контекстом — чтобы улики читались ГЛАЗАМИ, а не принимались на слово.""" + et_all = etalon() + R.PAIRS[PAIR]["wire"]() + for u in R.chosen(PAIR): + if u["uid"] not in et_all or (uid and not u["uid"].startswith(uid)): + continue + et = et_all[u["uid"]] + t = R.arm_text(PAIR, arm, u["uid"]) + d = defects(u["source"], t, et) + n = sum(len(v) for v in d.values()) + print(f"\n{'=' * 100}\n{u['uid']} арм {arm} фаталов {n} " + f"эталон: рассказчик {et.get('род_голоса')} · " + f"говорящие {[(s['имя'], s['род']) for s in et.get('говорящие', [])]}") + for h in rod_hits(t): + print(f" род [{h['род']}] {'речь ' if h['речь'] else 'повес'} " + f"{h['слово']:14s} …{h['ктx']}…") + for cl in CLASSES: + for x in d[cl]: + print(f" ⛔ {cl:6s} {x['слово'][:24]:24s} {x['почему']}") + return 0 + + +def cmd_selftest() -> int: + bad = 0 + + def ck(n: str, ok: bool, d: str = "") -> None: + nonlocal bad + bad += not ok + print(f"[{'OK ' if ok else 'ПРОВАЛ'}] {n}" + (f" {d}" if d else "")) + + # ── 1. ОТБОР ФОРМ. Гейт стоит на том, чем первая редакция болела. + for txt, want in (("Габриэль пожал плечами. — Я рассказал ей всё.", ["рассказал"]), + ("Фиби. Пьющий пепел. Битва при Санкте.", []), + ("Я поймала себя на мягкой улыбке.", ["поймала"]), + ("— Дело не в Диор, — прорычал я. — Поедешь с нами.", ["прорычал"]), + ("Это была молитва, поняла я.", ["поняла"]), + ("Он повесил голову, и я отвернулся к лошади.", ["отвернулся"])): + got = [h["слово"] for h in rod_hits(txt)] + ck(f"отбор форм: {txt[:44]!r}", got == want, f"нашлось {got}, ожидалось {want}") + + # ── 2. РЕЧЬ ПРОТИВ ПОВЕСТВОВАНИЯ — механическое правило на наблюдённых формах панели. + for txt, want in (("— Дело не в Диор, — прорычал я. — Поедешь с нами.", False), + ("— Я велел тебе сказать мэтру, что вернусь.", True), + ("Я подошёл к Хоакину и сжал его плечо.", False), + ("— Где я была? — Глаза мои сузились.", True), + ("— Благого рассвета, брат. — Я кивнул здоровяку.", False), + # ⛔ ВОЗОБНОВЛЕНИЕ РЕПЛИКИ ПОСЛЕ СЛОВ АВТОРА — на этом первая редакция и + # ломалась: третий кусок абзаца снова речь, а не повествование. + ("— Вряд ли, — фыркнул Жан-Франсуа. — Нет, я сбежал в Огюстен.", True), + ("— Да, — сказал он, — но я ушёл первым.", True)): + h = rod_hits(txt) + ck(f"речь/повествование: {txt[:44]!r}", bool(h) and h[0]["речь"] == want, + f"{'речь' if h and h[0]['речь'] else 'повествование'}, ожидалось " + f"{'речь' if want else 'повествование'}") + + # ── 3. ⛔ ФАЛЬСИФИКАЦИЯ: счётчик ОБЯЗАН найти брак, ПОДСАЖЕННЫЙ в заведомо чистый текст. + # Гейт, который зелен только на здоровом входе, не сторожит ничего — этим был болен селфтест + # Б8: он фильтровал арм по наличию файла клетки, файлов не было, и гейт зеленел вхолостую. + et_ok = {"род_голоса": "ж", "говорящие": [], + "латиница_законна": ["oui"], "приёмы": [{"текст": "P A T I E N C E"}]} + clean = "Я поймала себя на улыбке.\nЭто была молитва, поняла я.\nОн сказал oui, и я ушла.\nТ Е Р П Е Н И Е" + ck("фальсификация: чистый текст даёт НОЛЬ фаталов", + sum(len(v) for v in defects("", clean, et_ok).values()) == 0, + str({k: [x["слово"] for x in v] for k, v in defects("", clean, et_ok).items() if v})) + for name, sick, cl in ( + ("род сломан в повествовании", clean.replace("Я поймала", "Я поймал"), "род"), + ("род сломан вторым местом", clean.replace("поняла я", "понял я"), "род"), + ("непереведённый кусок исходника", clean.replace("и я ушла", "и я ушла, swift as silver"), "язык"), + ("разрядка потеряна", clean.replace("\nТ Е Р П Е Н И Е", ""), "приём"), + # ⛔ приём УДЕРЖАН, но слово НЕ ПЕРЕВЕДЕНО — латиница в разрядку. Первая редакция + # класса «язык» этого не видела: её регекс требовал двух букв подряд. + ("разрядка удержана, но по-английски", + clean.replace("Т Е Р П Е Н И Е", "P A T I E N C E"), "язык")): + got = defects("", sick, et_ok) + ck(f"фальсификация: счётчик ЛОВИТ «{name}»", bool(got[cl]), + f"класс «{cl}»: {[x['слово'] or x['почему'] for x in got[cl]] or 'ПУСТ — брак не пойман'}") + # обратная сторона: объявленная эталоном вставка браком НЕ считается + ck("законная иноязычная вставка эталона браком НЕ считается", + not lang_defects("Он сказал oui.", et_ok)) + ck("римская цифра браком НЕ считается", not lang_defects("Людовик VIII умер.", et_ok)) + + # ── 4. ЭТАЛОН ПОКРЫВАЕТ ПАНЕЛЬ, И КАЖДАЯ ГЛАВА В НЁМ ОБЪЯВЛЕНА ЯВНО. + # ⚠ «Главы нет в эталоне» обязано быть ПРОВАЛОМ, а не тихим пропуском: `collect` отбирает + # только главы эталона, и молчаливая недостача урезала бы панель ровно тем классом, против + # которого весь план и написан. + if not ETALON.exists(): + ck("эталон снят и лежит рядом", False, f"нет файла {ETALON.name}") + else: + et_all = etalon() + R.PAIRS[PAIR]["wire"]() + us = [u["uid"] for u in R.chosen(PAIR)] + ck("эталон покрывает ВСЕ главы панели", all(u in et_all for u in us), + f"нет в эталоне: {[u for u in us if u not in et_all]}") + need = ("род_голоса", "говорящие", "латиница_законна", "приёмы", "определим_по_окну") + miss = {u: [k for k in need if k not in et_all.get(u, {})] for u in us if u in et_all} + ck("у каждой главы эталона объявлены все четыре поля", + not any(miss.values()), str({u: v for u, v in miss.items() if v})) + ck("род рассказчика объявлен ЗНАЧЕНИЕМ, а не пропуском", + all(et_all[u].get("род_голоса") in ("ж", "м", None) for u in us if u in et_all), + str({u: et_all[u].get("род_голоса") for u in us + if u in et_all and et_all[u].get("род_голоса") not in ("ж", "м", None)})) + print(f"\n{'ПРИБОР ГОДЕН' if not bad else f'ПРОВАЛОВ: {bad}'}") + return bad + + +if __name__ == "__main__": + a = sys.argv[1:] or ["--report"] + if a[0] == "--selftest": + sys.exit(1 if cmd_selftest() else 0) + elif a[0] == "--report": + sys.exit(report(tuple(x for x in a[1:] if x.isupper()) or PANEL)) + elif a[0] == "--hits": + sys.exit(hits(a[1], a[2] if len(a) > 2 else "")) + else: + raise SystemExit(f"⛔ неизвестный режим {a[0]!r}; знаю --selftest --report --hits")