Freeze the buying code and ceilings for the D17 run before the DeepSeek price cutover
This commit is contained in:
parent
c6c3ada39d
commit
0961a10d5d
3 changed files with 715 additions and 3 deletions
|
|
@ -183,3 +183,233 @@ eval/.venv/bin/python eval/conformance.py eval/dovodka/requirements.md --plan
|
|||
модель вернула `glm-5` (слаг сверен), медиана 2593 знака, **$0.046329** при потолке ФД-H $0.10.
|
||||
Пакет **$6.048749** из $6.85. Судейства ja-ноги ЕЩЁ НЕТ — нужен отдельный слепой проход.
|
||||
* **19:5x** — `tier2`: 12 ответов из 16 на диске.
|
||||
* **20:0x** — `tier2` ЗАКРЫТ на 16 единицах: плотность 3.77 (нулей 6% против 38%), пол 16 пар
|
||||
sd 2.63 → порог 1.84, маржевый декой +2.50 ПРОЙДЕН, грубый 16/16. Контрасты `T1` −0.12 ·
|
||||
`T2` +1.06 · `T3` +0.50 — все ниже порога; контроль `R0 vs F` −3.12 p=0.0042.
|
||||
⇒ вывод пака 23 ВОССТАНОВЛЕН на приборе с сертификатом. Секция Д15. Сессии #65–#68 закрыты.
|
||||
* **20:1x** — ⛔ НАХОДКА ВЛАДЕЛЬЦА: DeepSeek подорожал, прайс не пере-снят. `roster.cost()`
|
||||
ВЫЧИСЛЯЕТ `cost_usd` из зашитого пина (25.07: flash $0.14/$0.28, pro $0.435/$0.87), провайдер
|
||||
сумму не возвращает ⇒ **$6.05 — это «сколько стоило бы по июльскому прайсу», а не списанное**.
|
||||
DeepSeek = 61% расхода. Пере-счёт возможен точно и бесплатно (в клетках лежат все токены).
|
||||
ЖДЁМ: владелец с оркестратором пере-снимают цены и вносят в документацию — НАПОМНИТЬ.
|
||||
* **20:2x** — ja-нога: заведён `ja6.py` (свой ключ/соль, панель `J0`·`J6`·`D0`+декой+маржевый,
|
||||
половины пола `J0`(p1)/`JFLO`(p2) РАЗВЕДЕНЫ ПО НАБОРАМ — дефект `tier` не повторяется, донор
|
||||
декоя чередуется). ФД-H поднят 0.10 → 0.15 под покупку пола (9 генераций РЕДАКТОРА: пол оси Д6
|
||||
снят с точечного фиксера и даёт 4 близнеца из 8). Фриз `22a8a6b`.
|
||||
⚠ ПОРЯДОК ПО СЛОВУ ВЛАДЕЛЬЦА: сперва СВОЙ прогон (claude), потом пакет Sol.
|
||||
* **20:4x** — ЗАКРЫТ ДОЛГ: **гейт наклона** `eval/dovodka/naklon.py` (селфтест на синтетике с
|
||||
известным ответом). Прогнан по 7 проходам, пробоев НЕТ. Существенно: наклон крупный там, где
|
||||
панель узкая (`border` +0.26, Д1 +0.28, Д6 +0.20 ошибки на шаг метки), но вредит его
|
||||
ПРОИЗВЕДЕНИЕ на дисбаланс средних позиций армов, а оно ≤9% порога (Д1) и ≤5% (Д6).
|
||||
Гейт роняет проход при поправке >25% порога.
|
||||
* **20:5x** — ЗАКРЫТ ДОЛГ: дефект парсера `conformance.py:80` — не снимал markdown-экранирование
|
||||
`\|` и рвал ячейку улики пополам. Следствие в ОБЕ стороны: **R55 был ложно-КРАСНЫМ** (требование
|
||||
исполнено), **R37 — ложно-ЗЕЛЁНЫМ** (гейт замены японской книги не проверял ничего и теперь
|
||||
честно красный: дословного слова владельца на замену в журнале нет). Осталось 2 провала:
|
||||
R37 (провенанс ja-книги) и R64 (реестр не закоммичен — лендит оркестратор).
|
||||
* **20:5x** — ЗАКРЫТ ДОЛГ: пинг в `docs/PROGRESS.md` секция «Полигон» (итог сессии №2).
|
||||
* **20:5x** — `E1`≡`D0` 5/16 объявлен в Д14.4 (долг закрыт там же).
|
||||
* ⚠ Покупка пола ja-ноги дважды упиралась в таймаут оболочки (600с): редактор думает 60–90 с на
|
||||
клетку. Команда ИДЕМПОТЕНТНА (пропускает готовые), просто перезапускать.
|
||||
* **21:xx** — `ja6.py --sol` собирает ПАКЕТ ДЛЯ SOL командой (не руками): изолированный каталог
|
||||
`~/books/judging/ja6-sol/` + `ИНСТРУКЦИЯ.md` + `ПРОМТ-ДЛЯ-ХАРНЕССА.md`. Вшито: путь к ключу НЕ
|
||||
называется (изоляция вместо «не открывай blind-keys/») · путь записи в свой каталог · правила
|
||||
счёта В САМОМ ЗАДАНИИ (паритет П-4) · запрет дочерних агентов · все армы единицы в одной пачке ·
|
||||
запрет молчаливого ноля с объяснением, откуда он взялся.
|
||||
* ⚠ ПРЕ-РЕГ ОГРАНИЧЕНИЕ ja-ноги, записано ДО ответов: маржевый декой садится на 5 единиц из 9;
|
||||
`--wide-plants` (на другой японской книге давал 8/9) ПРОВЕРЕН и НЕ помогает — те же 5/9.
|
||||
Регексы посадок оказались не только пар-, но и КНИГО-зависимы.
|
||||
* ⚠ Покупка пола зависла на клетке `dv-h-jflo-e9cad28783` (>7 мин, замок держит ЖИВОЙ процесс —
|
||||
снимать нельзя). Класс известен: в паке 22 вызов держал замок 74 минуты. 7 пар из 9 уже есть;
|
||||
если клетка не придёт — эмитировать с семью и объявить в пре-реге.
|
||||
|
||||
## 9. ЕСЛИ СЕССИЯ ОБОРВЁТСЯ ЗДЕСЬ — ЧТО ДЕЛАТЬ СЛЕДУЮЩЕМУ
|
||||
|
||||
1. `ls ~/books/dovodka/dv-h-jflo-*.json | wc -l` — пол ja-ноги. Было 7 из 9; одна клетка
|
||||
(`e9cad28783`) зависала >9 мин, замок снимать ТОЛЬКО если процесс мёртв
|
||||
(`ps -eo pid,cmd | grep "[j]a_axis.py --jfloor"`). Добор идемпотентен: `ja_axis.py --jfloor`.
|
||||
Семи пар для описательной оси ДОСТАТОЧНО — можно эмитировать не дожидаясь.
|
||||
2. `eval/.venv/bin/python eval/dovodka/ja6.py --emit` → 18 заданий (p1/p2) в
|
||||
`~/books/judging/ja6/`, ключ `~/books/dovodka/blind-keys-ja6/` (судье НЕ давать).
|
||||
3. Зарегистрировать сессии ДО запуска: `runs.py --claim ja6 p1 <ток> <ток> <ток> <ток>`.
|
||||
4. Отсудить СВОИМ семейством (агенты, задание самодостаточно, промт-рамку взять из
|
||||
`tier2`-воркфлоу: запрет diff/difflib, запрет дочерних агентов, изоляция каталога).
|
||||
5. `ja6.py --score` → гейты (плотность, декой, пол, маржевый) и контраст `J6/J0`.
|
||||
⚠ ЕСЛИ ХОТЬ ОДИН ГЕЙТ КРАСНЫЙ — пакет Sol НЕ отдавать, идти к владельцу.
|
||||
6. Если зелено: `ja6.py --sol` → пакет в `~/books/judging/ja6-sol/`, отдать владельцу.
|
||||
После его прогона: `ja6.py --score-sol`.
|
||||
7. Закрыть сессии `runs.py --done <n>`, дописать секцию Д16 в отчёт, обновить пинг PROGRESS.
|
||||
|
||||
**НЕ ЗАБЫТЬ НАПОМНИТЬ ВЛАДЕЛЬЦУ:** пере-счёт денег под настоящий прайс DeepSeek (он с
|
||||
оркестратором снимает цены). `roster.cost()` вычисляет `cost_usd` из пина 25.07 — весь леджер
|
||||
фазы это НЕ измерение, а оценка по устаревшей таблице. Токены в клетках есть, пере-счёт мгновенный.
|
||||
* **21:xx** — ja-нога ЭМИТИРОВАНА и пошла в судейство: 16 заданий (две единицы без набора p2 —
|
||||
их клетки пола не докупились), сессии #69–#72 зарегистрированы ДО запуска, воркфлоу
|
||||
`wf_5b498c36-7bd`. Секция **Д16** записана в отчёт ДО ответов (пре-рег + три ограничения).
|
||||
Зависший процесс покупки умер по таймауту, просроченный замок снят законно (процесс мёртв).
|
||||
* **ГЛАВНЫЙ ВЫВОД СЕССИИ, если всё прочее потеряется:** дуга 19→23 отвечала на вопрос «какая
|
||||
модель лучше редактор» (ответ устойчив: боевую связку не бьёт ни сильный тир за ×9 цены, ни
|
||||
дешёвые контуры), но продуктовый вопрос владельца — translationese — она не мерила. Разложение
|
||||
по осям: контуры проигрывают ПРОЗОЙ, а не смыслом (`A3` верность −0.26 при языке −1.61; `A6`
|
||||
верность +0.12). Смысл дешёвые схемы держат, ткань — нет и не могут: фиксер трогает 0.2–3.7%
|
||||
знаков. **Ни один арм за пять экспериментов не пробовал СПЛОШНУЮ ДЕШЁВУЮ ПЕРЕРАБОТКУ ПРОЗЫ** —
|
||||
переписать весь текст, но дешевле полного редактора. Там и лежит незакрытый вопрос.
|
||||
* **21:xx** — ЯПОНСКАЯ НОГА ОТСУЖЕНА первым семейством, ВСЕ ГЕЙТЫ ЗЕЛЁНЫЕ. 9 единиц, 48 клеток,
|
||||
замечаний годности 0. Плотность 2.38 (нулей 15%) · пол 7 пар sd 2.05 → порог 2.17 · грубый декой
|
||||
+2.89 ПРОЙДЕН · маржевый +2.80 ПРОЙДЕН (на 5 единицах, объявлено ДО).
|
||||
**`J0` dspro 1.44 · `JFLO` (вторая генерация ТОГО ЖЕ dspro) 1.86 · `J6` glm-5 1.89 · `D0` 4.22.**
|
||||
`J6/J0` −0.44 p=0.6875 ниже порога · `J0/D0` +2.78 p=0.0039 перешёл.
|
||||
⇒ **разница между ДВУМЯ редакторами (0.44) не больше разницы между двумя прогонами ОДНОГО
|
||||
редактора (0.42)** — самый чистый способ сказать «не различимо».
|
||||
⇒ **H-4 НЕ ПОДТВЕРЖДАЕТСЯ на всех трёх парах**: dspro первый на zh, en (1.31 против 2.72) и
|
||||
ja (1.44 против 1.89). Требование заказа :115 исполнено ВПЕРВЫЕ. Секции Д16.1/Д16.2.
|
||||
* **21:xx** — ПАКЕТ SOL СОБРАН: `~/books/judging/ja6-sol/` (16 заданий + ИНСТРУКЦИЯ.md +
|
||||
ПРОМТ-ДЛЯ-ХАРНЕССА.md). Проверено: тела побайтно равны судимым (16/16, различие ровно в строке
|
||||
пути записи) · утечки ключа НЕТ · в каталоге ничего кроме заданий и пустых ответов.
|
||||
Отдан владельцу. После его прогона: `ja6.py --score-sol`. Сессии #69–#72 закрыты (72 из 80).
|
||||
* **21:xx** — ЗАКРЫТ ДОЛГ (частично): реестр требований. Шесть самореферентных улик заменены на
|
||||
АРТЕФАКТНЫЕ, все шесть прошли: R40 (грепала слово «японской ноги» и стояла зелёной, когда ноги
|
||||
НЕ БЫЛО → теперь считает клетки `dv-h-j6-*` и прогоняет `ja6.py --score`) · R73 (грепала
|
||||
заголовок → теперь прогоняет селфтесты gain/naklon/adjud --controls) · R76 (грепала фразу →
|
||||
`money_d.py --selftest`) · R2 · R57 (грепала имя константы → проверяет пойманный декой в сырье) ·
|
||||
R61 (вела на гейт ЧУЖОГО пака `verify23.py`, который наклон фазы Д не проверяет → теперь
|
||||
`naklon.py`). Самореферентных 19 → 16; провалов по-прежнему 2 (R37 провенанс ja-книги,
|
||||
R64 реестр не закоммичен — лендит оркестратор).
|
||||
* **16.08** — СОБРАН ПРИБОР ТКАНИ: `eval/dovodka/chtenie.py --emit|--score`. Слепое чтение
|
||||
ВЛАДЕЛЬЦЕМ — минимальная форма П-6, который он принял 11.08 и который не был построен.
|
||||
Пакет → `~/books/chtenie-vladeltsa/` (ЧТЕНИЕ-zh.md 94 КБ, ЧТЕНИЕ-en.md 20 КБ), ключ ОТДЕЛЬНО
|
||||
в `~/books/dovodka/blind-keys-chtenie/` — не открывать до ответа.
|
||||
zh: единица `ed068182cf`, 5 вариантов (черновик · A0 · A3 · A6 · A4), ~9.7 тыс. знаков каждый.
|
||||
en: единица `27cb3a7e69`, 5 вариантов (черновик · E0 · E3 · E2 · E6), ~1.9 тыс. знаков.
|
||||
Владелец пишет ПОРЯДОК от лучшего к худшему + по фразе на вариант в `ОТВЕТ-{zh,en}.md`,
|
||||
затем `chtenie.py --score` де-слепляет. **Сверка его порядка с судейским счётом и есть ответ
|
||||
на вопрос, мерил ли риг 19→23 то, что нужно продукту.**
|
||||
* **16.08, СВЕРКА РЕВИЗИИ** (воскрешена после лимита): **65 находок из 131 в отчёт не попали.**
|
||||
Критичные, требуют пере-проверки следующей сессией:
|
||||
1. **H-1 МОЖЕТ ПЕРЕХОДИТЬ ПОРОГ.** Вердикт `A6/A0` определяют две пачки прогона, объявленного
|
||||
«валидацией цепочки», судимого 11.08 по НЕ замороженному промту, паритет не проверялся.
|
||||
Без них: пол n=13 sd 1.4058 → порог 1.0917, `A6/A0` −1.0938 → **ПЕРЕШЁЛ**. Отчёт печатает
|
||||
«НЕ УСТАНОВЛЕНА». Вместе с Д14.11 (`A6` по ВЕРНОСТИ +0.12) картина другая.
|
||||
2. Пачка `69de717f3f` осталась в замере, хотя её сессия АННУЛИРОВАНА за сравнение вариантов.
|
||||
Снятие двигает пороги обоих семейств и все контрасты.
|
||||
3. Унаследованный гейт честности пола свод не гоняет; на данных claude его вердикт —
|
||||
«ПОЛ СМЕЩЁН, боевые числа снимаются» (сдвиг +1.8 между p1/p2). claude несёт ОБА CONFIRM.
|
||||
4. Два пре-рег-правила о маржевом гейте противоречат: по букве П-1 пачка Sol аннулируется →
|
||||
у H-2а остаётся одно семейство → «эскалация», а не CONFIRM.
|
||||
5. Порог назван смещённым в ПРОТИВОПОЛОЖНЫЕ стороны двумя находками; ни одна не в отчёте ⇒
|
||||
калибровка порога неизвестна ПО ЗНАКУ.
|
||||
6. Донор декоя во всех 62 пачках Д4 — `A0` (тот же дефект, что объявлен у `tier` и починен в ja6).
|
||||
7. `A4`/`A1B`: клетки оплачены при НУЛЕВОМ изменении текста; `A4/A0` на 4 из 31 нулевой
|
||||
ПО ПОСТРОЕНИЮ (то же вскрытие сделано для `E4`, для `A4` — нет).
|
||||
Полный список: `/tmp/claude-1000/.../tasks/wrfw8ajqx.output` (эфемерный! перенести в ~/books).
|
||||
|
||||
---
|
||||
|
||||
## 10. ФИНАЛ СЕССИИ №2 (16.08) — передача
|
||||
|
||||
**ПРОМТ-ПЛАН ПРЕЕМНИКУ: `docs/POLYGON_PHASE_D_PLAN_16-08.md`** (10 разделов, ~450 строк).
|
||||
Он самодостаточен: словарь терминов · решения владельца дословно · что построено · что
|
||||
установлено с числами · план из трёх шагов · долги · ловушки · мнение Fable · команды ·
|
||||
чем закрывается работа · как разговаривать с владельцем. Читать ЦЕЛИКОМ, не грепом.
|
||||
|
||||
**Решение владельца 16.08, меняющее прибор:** «Штрафовать за вольность нельзя — живой язык один
|
||||
из приоритетов бэкенда. Штрафовать можно только за перевирания смысла исходника. В остальном
|
||||
можно менять, убирать англоязычность, переставлять текст». ⇒ рубрика судьи переписывается,
|
||||
и старые судейские числа с новыми станут НЕСРАВНИМЫ. Санкция на траты и на пере-проведение
|
||||
эксперимента дана.
|
||||
|
||||
**Слепое чтение 16.08 (читал Fable по поручению владельца, владелец мнение одобрил):**
|
||||
zh Спирмен +0.80 (прокси держится, но `A3` — ставка владельца — у читателя ПОСЛЕДНИЙ, ниже
|
||||
голого черновика) · **en Спирмен −0.10 (связи нет; однопроходка `E2` первая, боевая связка `E0`
|
||||
третья)**. Читатель ВСЛЕПУЮ предсказал механизм: «у Т3 отклонений больше, а читается лучше;
|
||||
счётчик должен был поставить его ниже» — так и вышло. Улики: `~/books/chtenie-vladeltsa/ОТВЕТ-*.md`.
|
||||
|
||||
**Персистировано человекочитаемым (владелец просил не jsonl):**
|
||||
`~/books/dovodka/СВЕРКА-РЕВИЗИИ-16-08.md` — 65 неотражённых находок, 7 противоречий телу отчёта,
|
||||
12 инструментов, признанных негодными внутри самой ревизии.
|
||||
|
||||
**Аудит собственного плана нашёл и закрыл пять пробелов:** не было словаря терминов (после
|
||||
компакта план был бы нечитаем) · не сказано, что 16.08 уже наступило и подорожание, вероятно,
|
||||
УЖЕ случилось · не перечислены все четыре места, где живёт рубрика · не названы пути ответов
|
||||
слепого чтения · битая ссылка на несуществующий §5.4 · не было раздела «чем закрывается работа».
|
||||
|
||||
**Деньги:** $6.085489 из $6.85. ⚠ Это оценка по прайсу от 25.07, а не списанное: `roster.cost()`
|
||||
вычисляет из зашитого пина. Владелец с оркестратором снимают цены — НАПОМНИТЬ.
|
||||
**Судейских сессий:** 72 (кап 80 снят словом владельца).
|
||||
**Коммиты сессии:** `a03ac66`, `8c68828`, `22a8a6b` — только пре-рег-фризы. Остальное лендит оркестратор.
|
||||
|
||||
## 11. ХВОСТ 16.08 — после полного перечитывания плана
|
||||
|
||||
* **Sol по японской ноге прогнан владельцем, контроли НЕ взял:** декой +2.22 и маржевый +1.80
|
||||
против собственного порога 2.80. Пачка по норме аннулируется; направление совпало с моим
|
||||
семейством (`J6/J0` −1.00 против −0.44). Вывод H-4 не меняется, но стоит на ОДНОМ семействе.
|
||||
* **Починен `ja6.py read()`**: не видел плоский `answers/` внешнего пакета и печатал «ответов нет».
|
||||
* **Цены пере-сняты — но только в бэкенде.** `models.yaml` несёт пик (`prices_checked 2026-08-15`),
|
||||
`eval/tenant_panel/roster.py:33-35` — ПО-ПРЕЖНЕМУ июльский. Следующая покупка снова посчитается
|
||||
неверно. Пере-счёт фазы: в кассе $5.40 (DeepSeek), по пику **$15.51 (×2.87)**, по офф-пику ~$8.95.
|
||||
⇒ смета следующего захода ~$2.9 пик / ~$1.7 офф-пик; **правило ничьей может пере-решиться**
|
||||
(`pro` подорожал втрое, `glm-5` — Z.AI, не дорожал; разрыв ×9 сжался).
|
||||
* ⛔ **ОДНОПРОХОДКА ЛОМАЕТ БАНК — блокер, найден владельцем.** `terminologist.md:22`: терминолог
|
||||
выбирает канон по ВАРИАНТАМ ЧЕРНОВИКОВ. Без черновика майнингу не из чего собирать свидетельства.
|
||||
⇒ однопроходка — альтернатива только ВТОРОМУ проходу, не связке. И это объясняет, почему чтение
|
||||
поставило её первой: на ОДНОЙ главе банк не нужен, на книге в 1500 глав имена разъедутся.
|
||||
* **Порядок плана изменён по замечанию владельца:** рубрика → покупка новых армов → ОДНО чтение по
|
||||
полной панели → судейство. Читать по всему один раз, а не дважды по кускам.
|
||||
* **Полное перечитывание плана нашло шесть расхождений** — все внесены. Вывод для себя: «прочитал
|
||||
структуру» ≠ «прочитал»; аудит по заголовкам пропустил устаревшую денежную секцию целиком.
|
||||
* **16.08, финальные правки плана по замечаниям владельца:**
|
||||
1. **Однопроходка — НЕ блокер.** Поправка владельца: «допустима, как вариант чтоб оттуда после
|
||||
вырезать термины и edit точечным редактором их заменить». Её выход тоже перевод ⇒ годится
|
||||
терминологу как свидетельство. Заведён кандидат **`K7`: однопроходка → майнинг банка из её
|
||||
выхода → канон-фиксер**. На en он стоит столько же, сколько связка (~0.0091 против 0.00885),
|
||||
а по слепому чтению однопроходка там читалась ЛУЧШЕ — самый дешёвый способ проверить.
|
||||
2. **Промт черновика — из «ловушки» в КАНДИДАТА `K8`.** Был записан как наблюдение, хотя владелец
|
||||
задал его как вопрос архитектуры. 22 строки против 41; у редактора есть блок дискурс-перевёрстки
|
||||
и FEWSHOT из трёх примеров, у переводчика — одна строка. Замер стоит ЦЕНУ ЧЕРНОВИКА (~$0.03
|
||||
на 16 единиц), самый дешёвый кандидат и ни разу не проверенный. ⚠ Сверить до замера, был ли
|
||||
FEWSHOT перенесён в `A2` — из эрраты Э-5 это не следует.
|
||||
3. **Панель черновой роли** (6 моделей эксп-22, ничья → побеждает дешёвый) внесена в §3.6а:
|
||||
«поставить дипсик-про черновиком» уже проверено и не выиграло ⇒ низкое качество черновика —
|
||||
свойство РОЛИ, а не модели.
|
||||
4. **Три «зелёных» инструмента, признанных негодными внутри ревизии**, названы поимённо:
|
||||
`promptdiff.py`, `canon.py`, `material_ja.py`.
|
||||
5. **Точечный ремонт не выброшен ратификацией**: D39.117 п.3 принял его как механический
|
||||
ПРЕ-ГЕЙТ ПЕРЕД редактором и «ремонт только с банком»; число «$0.0002 чинит всё» пало.
|
||||
|
||||
---
|
||||
|
||||
## 12. СЕССИЯ №3 (16.08, после компакта) — ЗАХОД Д17
|
||||
|
||||
**Работа по плану `eval/dovodka/PLAN-16-08.md`. Порядок шагов ПЕРЕСТАВЛЕН, основание числом:**
|
||||
вендор переводит DeepSeek на пик/офф-пик в 16:00 UTC 16.08 (сноска прайс-страницы, факт-чек 15.08
|
||||
в `models.yaml`). До перелома заход стоит **$1.06**, после — **$3.17**. Рубрика к покупке
|
||||
отношения не имеет (она нужна судейству), поэтому: КУПИТЬ → починить рубрику → отсудить.
|
||||
|
||||
**Построено:** `eval/dovodka/zakhod.py` — покупающий код захода. Армы `Z8` (обогащённый черновик),
|
||||
`Z8R` (он же + перепис), `Z1` (критик → ПОЛНЫЙ перепис), `Z7` (однопроходка + канон-фиксер),
|
||||
`ZF` (вторая генерация связки = пол новой рубрики). Бесплатные `ZD`/`Z0`/`ZP` берутся у осей.
|
||||
Касса: заведены ФД-I (zh) и ФД-J (en) по $0.65, пакетный потолок $6.85 → $8.15.
|
||||
|
||||
**Три находки ДО единой покупки (все — вычиткой и `--dry`, не гейтами):**
|
||||
1. **FEWSHOT в промт не попадает НИ У КОГО** — `prompts.load_template` его дропает, в проде
|
||||
`stages[edit].few_shot: false`. Значит утверждение плана «у редактора есть FEWSHOT, у
|
||||
переводчика нет» НЕВЕРНО как основание для `K8`. Асимметрия реальна, но она в секции
|
||||
ДИСКУРС-ПЕРЕВЁРСТКИ, и переносится только она — иначе арм мерил бы то, чего в бою нет.
|
||||
2. **`deepseek-v4-flash` в роли РЕДАКТОРА уже мерялся** (эксп-22 Ф3, арм `R3`): −2.54 против
|
||||
боевого, проходит порог 2.03, плюс 3 клетки из 16 сожгли бюджет и одна вернула черновик
|
||||
побайтно. ⇒ идея «сплошная дешёвая переработка прозы дешёвой моделью» НЕ пустая клетка,
|
||||
она занята и проиграна. Из плана этот кандидат снят до покупки.
|
||||
3. **Свой двойной экземпляр `contour.py`**: `en_axis` держит свой, и его `wire()` настраивает
|
||||
хуки в НЁМ. Мой второй экземпляр остался с китайскими хуками — английские черновики читались
|
||||
китайским путём, возвращали пусто и объявлялись «БРАКОВАН гейтом проекта», то есть английская
|
||||
ось молча стала бы пустой. Поймано `--dry` до покупки.
|
||||
|
||||
**Починен фильтр замечаний критика** (`contour.critic_places` брал любую строку с дефисом):
|
||||
на zh **198 строк из 863 (23%)** — согласия критика. Первая редакция моего фильтра требовала
|
||||
разделителя «→» и теряла настоящие находки (2 из 3 выброшенных) — правило переделано на
|
||||
двустороннее: выбрасываем, только если принимающая формула в ХВОСТЕ вердикта И нет маркера
|
||||
дефекта. Проверено выборкой глазами. На en согласий почти нет (2 из 178).
|
||||
|
||||
**Пре-рег Д17** записан в отчёт ДО покупок: панель, правило решения, формула порога, мощность,
|
||||
статус осей, чего заход не может. Правило расхождения эндпойнтов объявлено ДО данных: при
|
||||
расхождении счёта и чтения побеждает ЧТЕНИЕ (приоритет владельца «живой язык»).
|
||||
|
|
|
|||
|
|
@ -77,6 +77,8 @@ TAGS = {
|
|||
"ФД-F": ("dv-f-*.json",), # H-1: A6 dspro-черновик + оба контура
|
||||
"ФД-G": ("dv-g-*.json",), # H-4: E6 второй редактор на en
|
||||
"ФД-H": ("dv-h-*.json",), # H-4: японская нога — второй редактор glm-5 на ja
|
||||
"ФД-I": ("dv-i-*.json",), # Д17: заход под починенную рубрику, китайская пара
|
||||
"ФД-J": ("dv-j-*.json",), # Д17: заход под починенную рубрику, английская пара
|
||||
}
|
||||
# ⚠ Потолки фаз = смета `plan.py` плюс МИНИМАЛЬНЫЙ запас, так чтобы их СУММА не превышала
|
||||
# пакетный потолок. Первая редакция округляла каждый вверх до цента и дала сумму 4.54 > 4.50 —
|
||||
|
|
@ -158,9 +160,23 @@ TAGS = {
|
|||
# он снят с ТОЧЕЧНОГО фиксера (операция почти детерминированная) и даёт 4 побайтных близнеца
|
||||
# из 8 пар. Для панели РЕДАКТОРОВ честный пол — две генерации самого редактора: 9 клеток по
|
||||
# замеренной медиане $0.0052 = $0.047. Пакетный потолок $6.85 не двигается, сумма фазовых 6.83.
|
||||
# ⚠ 16.08, САНКЦИЯ ВЛАДЕЛЬЦА («Новые траты я разрешаю, перепровести эксп я разрешаю»): заведены
|
||||
# ФД-I и ФД-J — заход Д17 под ПОЧИНЕННУЮ рубрику судьи. Число назвала сессия и записала здесь,
|
||||
# чтобы санкция была проверяема: смета $1.06 по действующему прайсу (16 единиц × 5 армов × 2 пары
|
||||
# по ЗАМЕРЕННЫМ медианам купленных клеток), потолки 0.65+0.65 несут запас 23% на перекупку
|
||||
# усечённых клеток — класс, который в этой фазе стоил денег четырежды.
|
||||
# ⚠ ПОЧЕМУ ЗАХОД ПОКУПАЕТСЯ СЕЙЧАС, А НЕ ПОСЛЕ ПОЧИНКИ РУБРИКИ. Вендор переводит DeepSeek на
|
||||
# пик/офф-пик в 16:00 UTC 16.08 (сноска прайс-страницы, факт-чек 15.08 в `models.yaml`). До этого
|
||||
# мгновения та же работа стоит $1.06, после — около $3.2. Рубрика к покупке отношения не имеет:
|
||||
# она нужна судейству, а тексты армов от неё не зависят. Порядок «сначала купить, потом чинить
|
||||
# рубрику» экономит ×3 и ничего не смешивает. `zakhod.price_gate` отказывает в покупке DeepSeek
|
||||
# после перелома, пока `roster.py` не пере-пинен, — иначе касса начнёт печатать неправду.
|
||||
# ⚠ ПАКЕТНЫЙ ПОТОЛОК $6.85 → $8.15 РОВНО НА ДЕЛЬТУ новых фаз плюс $0.02, чтобы инвариант
|
||||
# «сумма фазовых ≤ пакетного» держался (8.12 ≤ 8.15). Ни одна прежняя фаза не двигается.
|
||||
CEILINGS = {"ФД-A": 1.950, "ФД-B": 0.950, "ФД-C": 0.420, "ФД-D": 0.050,
|
||||
"ФД-E": 2.370, "ФД-F": 0.720, "ФД-G": 0.210, "ФД-H": 0.150}
|
||||
PACK_CEILING = 6.85
|
||||
"ФД-E": 2.370, "ФД-F": 0.720, "ФД-G": 0.210, "ФД-H": 0.150,
|
||||
"ФД-I": 0.650, "ФД-J": 0.650}
|
||||
PACK_CEILING = 8.15
|
||||
|
||||
M22.configure(ZONE=ZONE, OUT=OUT, TAGS=TAGS, CEILINGS=CEILINGS,
|
||||
PACK_CEILING=PACK_CEILING, GLOB_ALL="dv-*.json", ROSTER=ROSTER)
|
||||
|
|
@ -173,7 +189,8 @@ def report() -> None:
|
|||
tot = 0.0
|
||||
what = {"ФД-A": "Д4 edit-контур zh", "ФД-B": "Д3 en→ru несущая", "ФД-C": "Д6 ja разведка",
|
||||
"ФД-D": "Д7 самооценка", "ФД-E": "Д1 gemini", "ФД-F": "H-1 (A6)", "ФД-G": "H-4 (E6)",
|
||||
"ФД-H": "H-4 японская нога (glm-5 на ja)"}
|
||||
"ФД-H": "H-4 японская нога (glm-5 на ja)",
|
||||
"ФД-I": "Д17 заход под новую рубрику, zh", "ФД-J": "Д17 заход под новую рубрику, en"}
|
||||
for ph in TAGS:
|
||||
sp = Guarded(ph).spent()
|
||||
tot += sp
|
||||
|
|
|
|||
465
eval/dovodka/zakhod.py
Normal file
465
eval/dovodka/zakhod.py
Normal file
|
|
@ -0,0 +1,465 @@
|
|||
#!/usr/bin/env python3
|
||||
"""ЗАХОД Д17 — маленький честный повтор под ПОЧИНЕННУЮ рубрику. Платный.
|
||||
|
||||
⚠ ЗАЧЕМ ЭТОТ ЗАХОД ВООБЩЕ. Дуга 19→23 отвечала на вопрос «какая модель лучше в роли редактора» и
|
||||
ответила устойчиво. Продуктовый вопрос владельца другой — живая русская проза без translationese, —
|
||||
и под него прибора не было: слепое чтение 16.08 дало на английской оси Спирмена −0.10, то есть
|
||||
счёт ошибок и читаемость там НЕ СВЯЗАНЫ. Владелец 16.08 постановил: «штрафовать за вольность
|
||||
нельзя, штрафовать можно только за перевирания смысла исходника». Рубрика переписана, значит
|
||||
старые судейские числа с новыми несравнимы — и панель обязана быть пере-куплена и пере-сужена
|
||||
целиком, вместе со СВОИМ шумовым полом.
|
||||
|
||||
ЧТО ПОКУПАЕТСЯ (имена армов ОДНИ на обе пары, пара живёт в данных — норматив общности §0):
|
||||
|
||||
ZD голый черновик БЕСПЛАТНО, уже есть (D0 / якорный черновик)
|
||||
Z0 боевая связка черновик → перепис БЕСПЛАТНО, уже есть (A0 / E0) — ЭТАЛОН
|
||||
ZP однопроходка уравненного мандата БЕСПЛАТНО, уже есть (A2 / E2)
|
||||
Z8 ОБОГАЩЁННЫЙ ЧЕРНОВИК ПОКУПАЕТСЯ (flash) — вопрос владельца 16.08
|
||||
Z8R Z8 + боевой перепис ПОКУПАЕТСЯ (pro)
|
||||
Z1 критик → ПОЛНЫЙ ПЕРЕПИС по нему ПОКУПАЕТСЯ (pro) — ставка владельца в сильнейшей форме
|
||||
Z7 однопроходка + канон-фиксер ПОСЛЕ ПОКУПАЕТСЯ (pro) — поправка владельца 16.08 про банк
|
||||
ZF ВТОРАЯ генерация боевой связки ПОКУПАЕТСЯ (pro) — шумовой пол НОВОЙ рубрики
|
||||
|
||||
⚠ ПОЧЕМУ ПОЛ ПОКУПАЕТСЯ ЗАНОВО, А НЕ БЕРЁТСЯ СТАРЫЙ. Существующий пол осей снят с ТОЧЕЧНОГО
|
||||
фиксера — операции почти детерминированной, дающей побайтных близнецов (в эксп-23 контроль
|
||||
`CTRLfloorA` совпал с боевым армом в 16/16 и оказался пуст). Панель этого захода — панель
|
||||
ПЕРЕПИСЫВАТЕЛЕЙ, и честный её пол есть ДВЕ ГЕНЕРАЦИИ ОДНОГО И ТОГО ЖЕ переписывателя. Ровно так
|
||||
сделана японская нога (`JFLO`), и там это дало самый чистый вывод фазы: разница двух редакторов
|
||||
(0.44) не больше разницы двух прогонов одного (0.42).
|
||||
|
||||
⚠ ЧЕМ Z1 ОТЛИЧАЕТСЯ ОТ ПРОИГРАВШЕГО A3. У `A3` правщик был ТОЧЕЧНЫМ: ему запрещалось трогать всё,
|
||||
кроме перечисленных мест, и он двигал 0.2–3.7% знаков. Здесь мандат ПОЛНЫЙ — это боевой редактор,
|
||||
которому замечания критика лишь ДОБАВЛЕНЫ к его обычной работе. Разложение по осям (Д14.11)
|
||||
показало, что точечные контуры проигрывают ПРОЗОЙ, а не смыслом; Z1 снимает именно это ограничение.
|
||||
|
||||
⚠ ЗАМЕЧАНИЯ КРИТИКА ФИЛЬТРУЮТСЯ, И ЭТО ПОЧИНКА, А НЕ ОПТИМИЗАЦИЯ. `contour.critic_places` берёт
|
||||
ЛЮБУЮ строку, начинающуюся с дефиса, без разбора вердикта: на китайской оси 311 строк из 1696
|
||||
(18.3%) были ПОДТВЕРЖДЕНИЯМИ критика («верно», «допустимо», «не ошибка»), и фиксер получал их как
|
||||
задания на правку. Ставка владельца была испытана инструментом, который на пятой части работы
|
||||
правил заведомо исправное. Здесь фильтр явный, его отсев печатается числом, а старые клетки `A3`
|
||||
не трогаются — они куплены и остаются как есть, с объявленным дефектом.
|
||||
|
||||
⚠ ГЕЙТ ПЕРЕЛОМА ЦЕНЫ DeepSeek. Вендор переводит прайс на пик/офф-пик В 16:00 UTC 16.08.2026
|
||||
(сноска прайс-страницы, факт-чек 15.08 в `backend/configs/models.yaml`). До этого мгновения
|
||||
июльский пин `eval/tenant_panel/roster.py` ВЕРЕН и записанная цена клетки правдива; после —
|
||||
занижает втрое, и касса начнёт печатать неправду. Поэтому покупка DeepSeek после перелома
|
||||
ОТКАЗЫВАЕТСЯ, пока ростер не пере-пинен. Это не осторожность, а единственное, что отличает
|
||||
леджер-измеритель от леджера-фантазёра.
|
||||
|
||||
Запуск: zakhod.py --dry | --selftest | --buy [zh|en] [армы…] | --plan
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import datetime as dt
|
||||
import hashlib
|
||||
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
|
||||
|
||||
|
||||
# ⚠ КОНТУР БЕРЁТСЯ У ДРАЙВЕРА АНГЛИЙСКОЙ ОСИ, А НЕ ГРУЗИТСЯ ВТОРЫМ ЭКЗЕМПЛЯРОМ, И ЭТО НЕ
|
||||
# ПЕДАНТИЗМ. `en_axis` держит СВОЙ экземпляр `contour.py` (`_load("contour_en", …)`), и его
|
||||
# `wire()` настраивает хуки баз ИМЕННО В НЁМ. Свой второй экземпляр остался бы с китайскими
|
||||
# хуками: английские черновики читались бы китайским путём, возвращали пусто и объявлялись
|
||||
# «БРАКОВАН гейтом проекта» — то есть английская ось молча стала бы пустой. Поймано `--dry`
|
||||
# до единой покупки; класс дефекта тот же, что стоил фазе семи оплаченных клеток 10.08.
|
||||
EN = _load("en_axis_z", ZONE / "en_axis.py")
|
||||
C = EN.C
|
||||
MONEY, PR, ROSTER, ED22, PARA = C.MONEY, C.PR, C.ROSTER, C.ED22, C.PARA
|
||||
OUT = MONEY.OUT
|
||||
|
||||
SALT = "zakhod-d17-2026-08-16" # соль отбора единиц; впечатывается в пре-рег ДО покупок
|
||||
N_UNITS = 16 # мощность объявлена пре-регом Д17, здесь она же
|
||||
DRAFT_MODEL = "deepseek-v4-flash"
|
||||
EDITOR = "deepseek-v4-pro"
|
||||
|
||||
# Перелом прайса DeepSeek: вендор-сноска, факт-чек 15.08 (`models.yaml` шапка).
|
||||
PRICE_CUTOVER = dt.datetime(2026, 8, 16, 16, 0, tzinfo=dt.timezone.utc)
|
||||
JULY_PIN_PRO = 0.435 # если в ростере всё ещё это — пин июльский
|
||||
|
||||
# ── ПАРА КАК ДАННЫЕ ───────────────────────────────────────────────────────────────────────────
|
||||
# Ни одна ветка ниже не спрашивает «а это китайский?». Всё, что у пары своё, — здесь.
|
||||
PAIRS = {
|
||||
"zh": {"para": lambda: PARA.ZH, "letter": "i", "phase": "ФД-I", "max_out": 16000,
|
||||
"onepass": "A2", "crit": "A3", "wire": lambda: C.configure(PARA.ZH),
|
||||
"units": lambda: C.units_ok()},
|
||||
"en": {"para": lambda: PARA.EN, "letter": "j", "phase": "ФД-J", "max_out": 32000,
|
||||
"onepass": "E2", "crit": "E3", "wire": EN.wire, "units": EN.units},
|
||||
}
|
||||
ARMS = ("Z8", "Z8R", "Z1", "Z7", "ZF") # покупаемые; ZD/Z0/ZP бесплатны
|
||||
FREE = ("ZD", "Z0", "ZP")
|
||||
|
||||
# ⚠ ПРАВИЛО ДВУСТОРОННЕЕ, И ЭТО ВЫВОД ЗАМЕРА, А НЕ ВКУС. Первая редакция требовала от строки
|
||||
# разделитель «→» и роняла всё прочее: на выборке это выбросило 3 строки, из которых ДВЕ были
|
||||
# настоящими находками («рассогласование реплик», «фраза суха — лучше так»). Ошибка в эту сторону
|
||||
# дороже противоположной: у Z1 правщик — ПОЛНЫЙ редактор, и лишнее подтверждение в списке он
|
||||
# просто перепишет как обычно, а потерянная находка не вернётся ничем.
|
||||
# Поэтому строка выбрасывается, ТОЛЬКО если (а) принимающая формула стоит в ХВОСТЕ вердикта —
|
||||
# то есть критик закончил согласием, — И (б) во всей строке нет ни одного маркера дефекта.
|
||||
CONFIRM_RX = re.compile(
|
||||
r"(?:вс[е]\s+верно|верно\b|правильно\b|корректн|допустим|уместн|не\s+ошибк|ошибки\s+нет|"
|
||||
r"претензий\s+нет|нареканий\s+нет|приемлем|адекватн|точно\s+переда|передано\s+верно|"
|
||||
r"соответствует\s+исходник|без\s+замечаний|(?:^|[\s,;—-])ок[.,;]?$)", re.IGNORECASE)
|
||||
DEFECT_RX = re.compile(
|
||||
r"(искаж|потер|неверн|ошибк|кальк|канцеляр|пропущ|инверт|рассоглас|подмен|выдум|отрицан|"
|
||||
r"не\s+соответств|лучше\b|следует\b|надо\b|стоит\b|заменить|исправ|сух|тяжел|громозд|"
|
||||
r"буквализм|подстрочник|не\s+переда|утрач)", re.IGNORECASE)
|
||||
CONFIRM_TAIL = 70 # знаков хвоста вердикта, где принимающая формула что-то значит
|
||||
|
||||
|
||||
def _is_confirmation(line: str) -> bool:
|
||||
"""Строка — согласие критика, а не место. `ё` нормализуется: критик пишет и «приёмлемо»."""
|
||||
s = line.replace("ё", "е").replace("Ё", "Е")
|
||||
verdict = s.split("→", 1)[1] if "→" in s else s
|
||||
return bool(CONFIRM_RX.search(verdict[-CONFIRM_TAIL:])) and not DEFECT_RX.search(s)
|
||||
|
||||
|
||||
def _pair(p: str) -> dict:
|
||||
if p not in PAIRS:
|
||||
raise SystemExit(f"⛔ неизвестная пара {p!r}; знаю {', '.join(PAIRS)}")
|
||||
return PAIRS[p]
|
||||
|
||||
|
||||
def tag(p: str, arm: str, uid: str) -> str:
|
||||
return f"dv-{_pair(p)['letter']}-{arm.lower()}-{uid}"
|
||||
|
||||
|
||||
def cell(tg: str) -> str:
|
||||
f = OUT / f"{tg}.json"
|
||||
if not f.exists():
|
||||
return ""
|
||||
d = json.loads(f.read_text(encoding="utf-8"))
|
||||
return (d.get("content") or "") if d.get("finish") == "stop" else ""
|
||||
|
||||
|
||||
# ── бесплатные армы: тексты, уже оплаченные прошлыми осями ────────────────────────────────────
|
||||
def free_text(p: str, arm: str, uid: str) -> str:
|
||||
"""ZD/Z0/ZP берутся у рига оси — он знает, где лежат клетки прошлых паков."""
|
||||
if arm == "ZD":
|
||||
return C.base_draft(uid)
|
||||
if arm == "Z0":
|
||||
return C.base_a0(uid)
|
||||
if arm == "ZP":
|
||||
return C.text_of(_pair(p)["onepass"], uid)
|
||||
raise SystemExit(f"⛔ {arm} не бесплатный арм")
|
||||
|
||||
|
||||
def crit_raw(p: str, uid: str) -> str:
|
||||
"""Ответ смыслового критика этой единицы — КУПЛЕН прошлой осью, здесь $0."""
|
||||
return cell(C.tag(_pair(p)["crit"], uid, "crit"))
|
||||
|
||||
|
||||
def critic_notes(p: str, uid: str) -> tuple[list[str], int]:
|
||||
"""(замечания критика, сколько строк отсеяно как согласия критика)."""
|
||||
txt = crit_raw(p, uid)
|
||||
if not txt.strip():
|
||||
return [], 0
|
||||
lines = [ln.strip("-•* \t") for ln in txt.splitlines() if ln.strip().startswith(("-", "•", "*"))]
|
||||
keep = [ln for ln in lines if not _is_confirmation(ln)]
|
||||
return keep[:C.PLACES_CAP], len(lines) - len(keep)
|
||||
|
||||
|
||||
# ── ОБОГАЩЁННЫЙ ЧЕРНОВИК (Z8): промт переводчика + мандат перевёрстки СВОЕЙ ПАРЫ ──────────────
|
||||
# ⚠ Вопрос владельца 16.08 дословно: «может, промт черновика от редактора сильно отличается и
|
||||
# черновик тут выступает в роли недоведённого до ума инструмента?» Текстом подтверждено: у
|
||||
# переводчика вся вёрстка — одна строка «НЕ копируй построчную разбивку», у редактора — секция
|
||||
# ДИСКУРС-ПЕРЕВЁРСТКА из четырёх шагов, обязательная операция передачи чужого синтаксиса русской
|
||||
# прозой. Черновик её не получал НИ РАЗУ за пять экспериментов.
|
||||
# ⚠ ПОПРАВКА К ПЛАНУ, найденная чтением кода: FEWSHOT в промт НЕ ПОПАДАЕТ НИ У КОГО —
|
||||
# `prompts.load_template` его дропает, потому что в проде `stages[edit].few_shot: false`. Значит
|
||||
# асимметрия «у редактора есть примеры» НЕВЕРНА, и Z8 переносит только то, что реально едет на
|
||||
# провод: секцию перевёрстки. Иначе арм мерил бы то, чего в бою нет.
|
||||
DISCOURSE_HEAD = "ДИСКУРС-ПЕРЕВЁРСТКА"
|
||||
|
||||
|
||||
def discourse_block(p: str) -> str:
|
||||
"""Секция перевёрстки из редакторского промта ЭТОЙ ЖЕ пары. Данные, не код."""
|
||||
core, _few, _user = PR.load_template(PR.PAIR_DIR[_pair(p)["para"]().key] / "editor.md")
|
||||
i = core.find(DISCOURSE_HEAD)
|
||||
if i < 0:
|
||||
raise SystemExit(f"⛔ в редакторском промте пары {p} нет секции {DISCOURSE_HEAD} — "
|
||||
"обогащать черновик нечем, арм Z8 не собирается")
|
||||
return core[i:].strip()
|
||||
|
||||
|
||||
def z8_msgs(p: str, src: str) -> list[dict]:
|
||||
"""Черновик с мандатом перевёрстки. Отличие от боевого черновика РОВНО ОДНО — эта секция."""
|
||||
key = _pair(p)["para"]().key
|
||||
m = PR.translator_msgs(src, None, pair=key)
|
||||
blk = PR.render(discourse_block(p), getattr(PR, PR.PAIR_BRIEF[key]), "", "")
|
||||
m[0]["content"] = m[0]["content"].rstrip() + "\n\n" + blk
|
||||
return m
|
||||
|
||||
|
||||
# ── ПОЛНЫЙ ПЕРЕПИС ПО ЗАМЕЧАНИЯМ КРИТИКА (Z1) ─────────────────────────────────────────────────
|
||||
Z1_HEAD = (
|
||||
"\n\nЗАМЕЧАНИЯ СМЫСЛОВОГО КРИТИКА к этому черновику (он читал исходник и перевод рядом). "
|
||||
"Устрани КАЖДОЕ из них. Это ДОБАВЛЕНИЕ к твоей обычной работе, а не замена: мандат "
|
||||
"художественной редактуры остаётся полным, и текст за пределами этих мест ты правишь так же, "
|
||||
"как правил бы без списка.\n")
|
||||
|
||||
|
||||
def z1_msgs(p: str, src: str, draft: str, notes: list[str]) -> list[dict]:
|
||||
key = _pair(p)["para"]().key
|
||||
bf = None if key == "zh-ru" else _pair(p)["para"]().bank_file
|
||||
m = PR.editor_msgs(src, draft, PR.law_block(PR.terms_in(src, bf), bf), pair=key)
|
||||
m[1]["content"] = m[1]["content"] + Z1_HEAD + "\n".join(f"- {n}" for n in notes)
|
||||
return m
|
||||
|
||||
|
||||
def editor_msgs(p: str, src: str, draft: str) -> list[dict]:
|
||||
"""Боевой редактор без изменений — им куплены Z8R и ZF."""
|
||||
key = _pair(p)["para"]().key
|
||||
bf = None if key == "zh-ru" else _pair(p)["para"]().bank_file
|
||||
return PR.editor_msgs(src, draft, PR.law_block(PR.terms_in(src, bf), bf), pair=key)
|
||||
|
||||
|
||||
# ── ОТБОР ЕДИНИЦ ──────────────────────────────────────────────────────────────────────────────
|
||||
def pool(p: str) -> list[dict]:
|
||||
"""Единицы, где ВСЕ бесплатные армы и ответ критика уже есть. Меньше — покупать не на чем."""
|
||||
_pair(p)["wire"]()
|
||||
out = []
|
||||
for u in _pair(p)["units"]():
|
||||
if all(free_text(p, a, u["uid"]).strip() for a in FREE) and crit_raw(p, u["uid"]).strip():
|
||||
out.append(u)
|
||||
return out
|
||||
|
||||
|
||||
def chosen(p: str) -> list[dict]:
|
||||
"""N_UNITS единиц, отобранных ДЕТЕРМИНИРОВАННО от соли захода.
|
||||
|
||||
⚠ Почему не «самые длинные» и не «первые по списку». Длина коррелирует с трудностью, а
|
||||
трудность — с тем, какой арм выигрывает; отбор по ней покупает часть вывода заранее. Отбор по
|
||||
хешу от объявленной ДО покупок соли не коррелирует ни с чем и воспроизводим кем угодно.
|
||||
"""
|
||||
us = pool(p)
|
||||
if len(us) <= N_UNITS:
|
||||
return us
|
||||
return sorted(us, key=lambda u: hashlib.sha256(f"{SALT}|{p}|{u['uid']}".encode()).hexdigest()
|
||||
)[:N_UNITS]
|
||||
|
||||
|
||||
# ── ГЕЙТ ПЕРЕЛОМА ЦЕНЫ ────────────────────────────────────────────────────────────────────────
|
||||
def price_gate() -> None:
|
||||
now = dt.datetime.now(dt.timezone.utc)
|
||||
pin = ROSTER.CANDIDATES[EDITOR][2]
|
||||
stale = abs(pin - JULY_PIN_PRO) < 1e-9
|
||||
left = (PRICE_CUTOVER - now).total_seconds() / 3600
|
||||
if now < PRICE_CUTOVER:
|
||||
print(f" цена DeepSeek: до перелома {left:.1f} ч, июльский пин ${pin}/1M ВЕРЕН")
|
||||
return
|
||||
if stale:
|
||||
raise SystemExit(
|
||||
"⛔ ПЕРЕЛОМ ЦЕНЫ DeepSeek УЖЕ НАСТУПИЛ (16:00 UTC 16.08.2026), а "
|
||||
f"`eval/tenant_panel/roster.py` всё ещё несёт июльский пин ${pin}/1M.\n"
|
||||
" Покупка ОТКАЗАНА: записанная цена клетки была бы втрое ниже списанной, касса\n"
|
||||
" печатала бы неправду, а проекционный гард резервировал бы втрое меньше нужного.\n"
|
||||
" Пере-пинить ростер (пик $1.32/$3.96 pro, $0.44/$1.32 flash) и повторить.")
|
||||
print(f" цена DeepSeek: перелом пройден, ростер пере-пинен (${pin}/1M) — покупка разрешена")
|
||||
|
||||
|
||||
# ── ПОКУПКА ───────────────────────────────────────────────────────────────────────────────────
|
||||
def _buy(led, tg: str, model: str, msgs: list[dict], max_out: int, **extra) -> None:
|
||||
rec = MONEY.purchase(led, tg, model, ED22.client(model),
|
||||
ROSTER.call_kwargs(model, msgs, max_out=max_out), **extra)
|
||||
if rec.get("skipped"):
|
||||
raise SystemExit(f"⛔ ГАРД ОТКАЗАЛ на клетке {tg} — прогон ОСТАНОВЛЕН.\n"
|
||||
" Резать панель или поднимать потолок решением сессии ЗАПРЕЩЕНО.\n"
|
||||
" Это СТОП и вопрос владельцу: назвать недостающую сумму.")
|
||||
|
||||
|
||||
def buy(p: str, which: list[str]) -> None:
|
||||
price_gate()
|
||||
cfg = _pair(p)
|
||||
cfg["wire"]()
|
||||
us = chosen(p)
|
||||
led = MONEY.Guarded(cfg["phase"], default_expect=0.009)
|
||||
mo = cfg["max_out"]
|
||||
print(f"\nпара {p} · единиц {len(us)} · армы {' '.join(which)} · касса {cfg['phase']}")
|
||||
for arm in which:
|
||||
for u in us:
|
||||
uid, src = u["uid"], u["source"]
|
||||
tg = tag(p, arm, uid)
|
||||
if cell(tg).strip():
|
||||
continue
|
||||
if arm == "Z8":
|
||||
_buy(led, tg, DRAFT_MODEL, z8_msgs(p, src), mo,
|
||||
role="translator", uid=uid, arm=arm)
|
||||
elif arm == "Z8R":
|
||||
d = cell(tag(p, "Z8", uid))
|
||||
if not d.strip():
|
||||
print(f" {uid}: обогащённого черновика нет — {arm} пропущен")
|
||||
continue
|
||||
_buy(led, tg, EDITOR, editor_msgs(p, src, d), mo,
|
||||
role="editor", uid=uid, arm=arm)
|
||||
elif arm == "Z1":
|
||||
notes, dropped = critic_notes(p, uid)
|
||||
if not notes:
|
||||
print(f" {uid}: замечаний критика нет — {arm} пропущен, объявить в отчёте")
|
||||
continue
|
||||
_buy(led, tg, EDITOR, z1_msgs(p, src, free_text(p, "ZD", uid), notes), mo,
|
||||
role="editor", uid=uid, arm=arm, notes=len(notes), notes_dropped=dropped)
|
||||
elif arm == "Z7":
|
||||
op = free_text(p, "ZP", uid)
|
||||
gaps = C.canon_gaps(src, op)
|
||||
if not gaps:
|
||||
C._free_cell(tg, op, role="fixer", uid=uid, arm=arm, places=0)
|
||||
continue
|
||||
places = [f"КАНОН: термин {g} передан не канонной формой либо пропущен"
|
||||
for g in gaps]
|
||||
_buy(led, tg, EDITOR, C.fix_msgs(src, op, places), mo,
|
||||
role="fixer", uid=uid, arm=arm, places=len(places))
|
||||
elif arm == "ZF":
|
||||
_buy(led, tg, EDITOR, editor_msgs(p, src, free_text(p, "ZD", uid)), mo,
|
||||
role="floor2", uid=uid, arm=arm)
|
||||
else:
|
||||
raise SystemExit(f"⛔ арм {arm} не покупается этим файлом")
|
||||
MONEY.report()
|
||||
|
||||
|
||||
# ── СМЕТА И ПРОВЕРКИ ──────────────────────────────────────────────────────────────────────────
|
||||
PRICE = {"Z8": 0.00060, "Z8R": 0.00790, "Z1": 0.00900, "Z7": 0.00758, "ZF": 0.00790}
|
||||
WHAT = {"Z8": "обогащённый черновик (flash + мандат перевёрстки)",
|
||||
"Z8R": "Z8 + боевой перепис — «лучше ли связка на лучшем черновике»",
|
||||
"Z1": "критик → ПОЛНЫЙ перепис по его замечаниям",
|
||||
"Z7": "однопроходка + канон-фиксер — банк без черновика",
|
||||
"ZF": "ВТОРАЯ генерация боевой связки — шумовой пол новой рубрики"}
|
||||
|
||||
|
||||
def cmd_dry() -> None:
|
||||
print(f"ЗАХОД Д17 · соль отбора {SALT} · единиц на ось {N_UNITS}\n")
|
||||
price_gate()
|
||||
tot = 0.0
|
||||
for p in PAIRS:
|
||||
us, pl = chosen(p), pool(p)
|
||||
print(f"\n=== пара {p} · пул {len(pl)} · взято {len(us)} · касса {_pair(p)['phase']} ===")
|
||||
nd = sum(len(critic_notes(p, u["uid"])[0]) for u in us)
|
||||
dr = sum(critic_notes(p, u["uid"])[1] for u in us)
|
||||
print(f" замечаний критика {nd}, отсеяно подтверждений и безадресных строк {dr} "
|
||||
f"({dr / max(nd + dr, 1):.0%})")
|
||||
sub = 0.0
|
||||
for a in ARMS:
|
||||
have = sum(1 for u in us if cell(tag(p, a, u["uid"])).strip())
|
||||
need = len(us) - have
|
||||
cost = need * PRICE[a]
|
||||
sub += cost
|
||||
print(f" {a:4s} есть {have:2d} · надо {need:2d} · ${PRICE[a]:.5f}/кл · "
|
||||
f"смета ${cost:.4f} {WHAT[a]}")
|
||||
ph = _pair(p)["phase"]
|
||||
sp = MONEY.Guarded(ph).spent() if ph in MONEY.CEILINGS else 0.0
|
||||
ceil = MONEY.CEILINGS.get(ph, 0.0)
|
||||
mark = "ВЛЕЗАЕТ" if sub <= ceil - sp else f"НЕ ВЛЕЗАЕТ (не хватает ${sub - (ceil - sp):.4f})"
|
||||
print(f" ИТОГО ${sub:.4f} · потолок {ph} ${ceil:.2f} · потрачено ${sp:.4f} → {mark}")
|
||||
tot += sub
|
||||
print(f"\nВЕСЬ ЗАХОД: ${tot:.4f} по действующему (июльскому) прайсу DeepSeek.")
|
||||
print(f"После перелома 16:00 UTC 16.08 та же работа стоила бы ${tot * 3.0:.4f} (пик ×3).")
|
||||
|
||||
|
||||
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 ""))
|
||||
|
||||
for p in PAIRS:
|
||||
us = chosen(p)
|
||||
ck(f"{p}: единиц ровно {N_UNITS}", len(us) == N_UNITS, f"их {len(us)}")
|
||||
ck(f"{p}: uid уникальны", len({u["uid"] for u in us}) == len(us))
|
||||
ck(f"{p}: отбор ДЕТЕРМИНИРОВАН (повтор даёт тот же набор)",
|
||||
[u["uid"] for u in chosen(p)] == [u["uid"] for u in us])
|
||||
ck(f"{p}: все три бесплатных арма есть на каждой единице",
|
||||
all(free_text(p, a, u["uid"]).strip() for a in FREE for u in us))
|
||||
u = us[0]
|
||||
# Z8 обязан отличаться от боевого черновика РОВНО мандатом перевёрстки — иначе арм пуст
|
||||
key = _pair(p)["para"]().key
|
||||
base = PR.translator_msgs(u["source"], None, pair=key)[0]["content"]
|
||||
z8 = z8_msgs(p, u["source"])[0]["content"]
|
||||
ck(f"{p}: Z8 = черновик + мандат перевёрстки", z8.startswith(base.rstrip())
|
||||
and DISCOURSE_HEAD in z8, f"дельта {len(z8) - len(base)} знаков")
|
||||
ck(f"{p}: в Z8 нет нераскрытых плейсхолдеров", "{{" not in z8)
|
||||
ck(f"{p}: FEWSHOT в Z8 не уехал (в бою его нет ни у кого)", "FEWSHOT" not in z8)
|
||||
# Z1 обязан быть БОЕВЫМ редактором плюс замечания, а не новым промтом
|
||||
notes, _ = critic_notes(p, u["uid"])
|
||||
z1 = z1_msgs(p, u["source"], free_text(p, "ZD", u["uid"]), notes or ["тест"])
|
||||
ed = editor_msgs(p, u["source"], free_text(p, "ZD", u["uid"]))
|
||||
ck(f"{p}: Z1 несёт системный промт боевого редактора ПОБАЙТНО",
|
||||
z1[0]["content"] == ed[0]["content"])
|
||||
ck(f"{p}: замечания критика уходят Z1 пользовательским сообщением",
|
||||
z1[1]["content"].startswith(ed[1]["content"]) and len(z1[1]["content"]) > len(ed[1]["content"]))
|
||||
ck(f"{p}: мандат редактуры в Z1 остался ПОЛНЫМ", "ДОБАВЛЕНИЕ к твоей обычной работе"
|
||||
in z1[1]["content"])
|
||||
# ZF обязан быть побайтной копией запроса Z0 — иначе это не пол, а другой арм
|
||||
ck(f"{p}: ZF = ТОТ ЖЕ запрос, что у боевой связки (пол, а не новый арм)",
|
||||
editor_msgs(p, u["source"], free_text(p, "ZD", u["uid"])) == ed)
|
||||
# фильтр критика обязан ловить подтверждения и не выедать находки целиком
|
||||
allk = sum(len(critic_notes(p, x["uid"])[0]) for x in us)
|
||||
alld = sum(critic_notes(p, x["uid"])[1] for x in us)
|
||||
ck(f"{p}: фильтр критика оставляет находки", allk > 0, f"осталось {allk}, отсеяно {alld}")
|
||||
ck(f"{p}: фильтр критика ЧТО-ТО отсеивает (дефект A3 был реален)", alld > 0)
|
||||
# теги: покрыты глобом кассы своей фазы и не сталкиваются с чужими
|
||||
tg = tag(p, "Z8", u["uid"])
|
||||
ck(f"{p}: тег покрыт глобом кассы {_pair(p)['phase']}",
|
||||
tg.startswith(f"dv-{_pair(p)['letter']}-"), tg)
|
||||
ck(f"{p}: фаза заведена в кассе", _pair(p)["phase"] in MONEY.CEILINGS)
|
||||
ck(f"{p}: теги армов различны", len({tag(p, a, u["uid"]) for a in ARMS}) == len(ARMS))
|
||||
# общие
|
||||
ck("пары не делят буквы тегов", len({v["letter"] for v in PAIRS.values()}) == len(PAIRS))
|
||||
ck("касса покупок смотрит в каталог фазы", MONEY.M22.BUY.OUT == OUT)
|
||||
ck("согласие критика опознаётся", _is_confirmation("цитата → передано верно"))
|
||||
ck("согласие с «ё» опознаётся (критик пишет «приёмлемо»)",
|
||||
_is_confirmation("цитата → приёмлемо"))
|
||||
ck("находка НЕ опознаётся как согласие", not _is_confirmation("цитата → адресат инвертирован"))
|
||||
ck("СМЕШАННАЯ строка остаётся находкой (дефект перевешивает согласие в хвосте)",
|
||||
not _is_confirmation("цитата → адресат инвертирован, но в остальном верно"))
|
||||
ck("строка без «→» не выбрасывается только за отсутствие стрелки",
|
||||
not _is_confirmation("Рассогласование реплик: реплика приписана не тому говорящему"))
|
||||
ck("гейт перелома цены знает дату вендора",
|
||||
PRICE_CUTOVER.isoformat() == "2026-08-16T16:00:00+00:00")
|
||||
print(f"\n{'ЗАХОД ГОДЕН К ПОКУПКЕ' if not bad else f'ПРОВАЛОВ: {bad}'}")
|
||||
return bad
|
||||
|
||||
|
||||
def cmd_plan() -> None:
|
||||
for p in PAIRS:
|
||||
us = chosen(p)
|
||||
print(f"\n=== {p}: {len(us)} единиц ===")
|
||||
for a in FREE + ARMS:
|
||||
have = sum(1 for u in us
|
||||
if (free_text(p, a, u["uid"]) if a in FREE else cell(tag(p, a, u["uid"])))
|
||||
.strip())
|
||||
print(f" {a:4s} {have:2d}/{len(us)}" + (" (бесплатно)" if a in FREE else ""))
|
||||
MONEY.report()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
a = sys.argv[1:] or ["--dry"]
|
||||
if a[0] == "--selftest":
|
||||
sys.exit(1 if cmd_selftest() else 0)
|
||||
elif a[0] == "--dry":
|
||||
cmd_dry()
|
||||
elif a[0] == "--plan":
|
||||
cmd_plan()
|
||||
elif a[0] == "--buy":
|
||||
pr = [x for x in a[1:] if x in PAIRS] or list(PAIRS)
|
||||
ar = [x for x in a[1:] if x in ARMS] or list(ARMS)
|
||||
for x in pr:
|
||||
buy(x, ar)
|
||||
else:
|
||||
raise SystemExit(f"⛔ неизвестный режим {a[0]!r}; знаю --dry --selftest --plan --buy")
|
||||
Loading…
Add table
Reference in a new issue