Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BcWeV2yiMWTjkeaQfSsYuL
361 lines
39 KiB
Markdown
361 lines
39 KiB
Markdown
# ПРЕ-РЕГИСТРАЦИЯ СТЕНДА — контролируемая проба редактора по четырём осям
|
||
|
||
**Дата: 02.09.2026. Ветка `polygon`. Сессия-исполнитель `textmachine-2f`.**
|
||
**Закон: `eval/dovodka/PLAN-01-09.md`** (фриз ДОКУМЕНТА — коммит `dc602e9`).
|
||
Промт исполнителя: `eval/dovodka/PROMPT-PROBE-4AXES.md`.
|
||
|
||
> Настоящий коммит — **ФРИЗ №1: СТЕНД**, и он ложится **ДО первой платной клетки**. `dc602e9` заморозил
|
||
> дизайн, модели, правило решения, потолок, рамку и сид; здесь замораживается всё остальное, что после
|
||
> первой покупки править уже нельзя: конфиги, скрипты, sha256 и правило кассы.
|
||
> **ФРИЗ №2** — пин сигнатуры Δ`prompt_tokens`, снятой пред-полётом (план §4: полосу нельзя было задать
|
||
> заранее). Оба объявляются владельцу вслух.
|
||
|
||
Машинная копия всего перечисленного — `prereg.json` рядом (её читает `chetyre.py --manifest`).
|
||
Замороженные копии конфигов и промптов — `stand/`. Они лежат в зоне полигона, потому что физически
|
||
конфиги живут в каталоге книги, а `books/` — **отдельный репозиторий**, и «фриз коммитом» там
|
||
неисполним по канону (план §5.5).
|
||
|
||
---
|
||
|
||
## 1. РАМКА ВЫБОРКИ — пинится первой, иначе «20 юнитов» читаются как ОТБОР
|
||
|
||
| что | значение |
|
||
|---|---|
|
||
| главы книги | **26–42** (17 глав) |
|
||
| нумерация в движке | **1–17** в колонке `chapter` БД ⚠ движок не умеет смещение глав |
|
||
| файл среза | `~/books/gu-zhenren/probe-4axes/guzhenren-ch26-42.gb18030.txt` |
|
||
| sha256 среза | `1ebcc9efb0fa5006548eba8599b58d4d5a44a201562271d0ff9f1eb9b803fccf` |
|
||
| размер | 97 408 Б GB18030 · CRLF · 17 заголовков · 47 519 знаков без переводов строк |
|
||
| резалка | `eval/dovodka/narezka.py --from 26 --to 42` (вход UTF-8, GB18030 на выходе) |
|
||
| **n юнитов** | **20** |
|
||
| каталог | **новый** `~/books/gu-zhenren/probe-4axes/` — не `coldrun-v16` (там три оплаченных edit-юнита) |
|
||
| отбора нет | все юниты диапазона в порядке движка; **юнит пред-полёта ВХОДИТ в n** |
|
||
|
||
**Как снято `n`, командой (`$0`, до первой покупки):**
|
||
|
||
```
|
||
$ ~/books/gu-zhenren/probe-4axes/bin/tmctl manifest --config ~/books/gu-zhenren/probe-4axes/book.yaml
|
||
chapters=17 units=20 chunks=35
|
||
source: 97408 bytes (sha256 1ebcc9efb0fa) · encoding gb18030 · zh→ru
|
||
```
|
||
|
||
✅ **МИНА НУМЕРАЦИИ СЛАБЕЕ, ЧЕМ БОЯЛСЯ ПЛАН — и это тоже улика, а не мнение.** План писал, что
|
||
соответствие «главы книги 26–42 ≡ главы среза 1–17» держится ТОЛЬКО записью в пре-реге. На деле у
|
||
движка есть СВОЙ носитель: чанкер разбирает китайский номер `第二十六节` и печатает в манифесте
|
||
заголовки **«Глава 26» … «Глава 42»** при позиционных `number` 1…17. То есть соответствие
|
||
восстанавливается из артефакта прогона, а не только из этого документа. Команда:
|
||
|
||
```
|
||
$ python -c "import json;m=json.load(open('.../guzhenren-probe4.db.manifest.json'));
|
||
print([(c['number'],c['heading'],c['units_total']) for c in m['chapters']])"
|
||
(1,'Глава 26',1) (2,'Глава 27',1) (3,'Глава 28',2) … (17,'Глава 42',1) Σ units = 20
|
||
```
|
||
|
||
Три главы (28, 37, 38) дают по два юнита, остальные по одному — отсюда 20, а не 17.
|
||
|
||
⚠ **ОТСТУПЛЕНИЕ ОТ ОЖИДАНИЯ ПЛАНА, названное до покупки:** план ждал ~24 юнита по пропорции холодного
|
||
прогона (14 на 10 глав). Фактически **20**. Это не нарушение — §6 плана прямо говорит, что вариант
|
||
задаётся ДИАПАЗОНОМ ГЛАВ, а «24» есть ожидание, а не цель. **Следствие для мощности объявляется здесь,
|
||
а не после чисел:** при σ=1.2 MDE растёт с ×2.02 (n=24) до **≈×2.16** (n=20).
|
||
|
||
## 2. СИД И ПОРЯДОК
|
||
|
||
Сид **`20260902`**. Порядок рук внутри юнита — `eval/dovodka/poryadok.py`, перестановка на sha256
|
||
(не `random`: он не обещает стабильности между версиями Python). Контракт: четыре руки креста —
|
||
перестановкой, **`glm-off` ВСЕГДА пятый**, чтобы при денежном гарде терялся референс, а не пара, на
|
||
которой стоит E1. Выпавший порядок всех 20 юнитов — в `prereg.json` (`порядок_рук`).
|
||
|
||
## 3. КРЕСТ И МОДЕЛИ — фиксированы
|
||
|
||
| рука | промпт | `stages[edit].reasoning` | модель | что уходит на провод |
|
||
|---|---|---|---|---|
|
||
| `p7-off` | `editor-p7.md` (июльский) | `"off"` | `deepseek-v4-pro` | ключа `reasoning_effort` НЕТ ⇒ вендор-дефолт |
|
||
| `p7-low` | тот же | `"low"` | `deepseek-v4-pro` | `reasoning_effort:"low"` |
|
||
| `p9-off` | `editor-p9.md` (сегодняшний) | `"off"` | `deepseek-v4-pro` | ключа нет |
|
||
| `p9-low` | тот же | `"low"` | `deepseek-v4-pro` | `low` |
|
||
| ⭐ `glm-off` | `editor-p9.md` | `"off"` | **`glm-5`** | `extra_body {thinking:{type:disabled}}` — **референс, НЕ фактор креста** |
|
||
|
||
Черновик `deepseek-v4-flash`@`low`, хоп эскалации `deepseek-v4-pro`, терминолог и классификатор
|
||
`deepseek-v4-flash`@`low` — **константы во всех пяти руках**. **Судья не вызывается.**
|
||
|
||
**Провод проверен по коду, не по памяти:** `capability.go:236-239` — ветка `ReasoningNone` пишет
|
||
`reasoning_effort` только если значение не пусто и не `"off"`; у `deepseek-v4-pro` в `models.yaml`
|
||
блока `capabilities.reasoning` нет вовсе ⇒ `off` = ключ не отправлен, `low` = отправлен буквально.
|
||
У `glm-5` `control: extra_body_disable`, `off_extra_body: {thinking:{type:disabled}}` ⇒ у неё `off`
|
||
это НАСТОЯЩЕЕ выключение размышления.
|
||
|
||
**Различие двух промптов — ровно одна строка** (проверено `diff`): в `editor-p9.md` к правилу о
|
||
повторах добавлена оговорка про авторский рефрен. Метка `prompt_version` у обоих одна
|
||
(`v3-discourse-reflow`), поэтому ось берётся **по SHA**, а не по метке.
|
||
|
||
## 4. SHA256 — всё, что после этого коммита не правится
|
||
|
||
Полный список — `prereg.json` (`sha256`). Несущие:
|
||
|
||
```
|
||
1ebcc9efb0fa5006548eba8599b58d4d5a44a201562271d0ff9f1eb9b803fccf срез глав 26-42
|
||
5ed4ee7ed5bc6c48102798a55567fb6752da3309caff8005f8167f8133e792fc бинарь tmctl (main @ bd2077b)
|
||
21b7735009c25679abc42e018692d3fde93beb3146b157603b5d49acda81ee01 models.yaml (побайтно один в обоих деревьях)
|
||
2b84dee34b0861637a055fee60372d2553f85ffa4c1b535c1e781f5167e8c3a1 editor-p7.md (P₇, июльский)
|
||
1ad4544e564a9b4049231e79e961a9cbb85bc39de07c5ce72cdbc8d92cc68999 editor-p9.md (P₉, сегодняшний)
|
||
3d2a7123bafc22cc6f9f93c62d2fb4cce3bb4d311437f14cbec6411fe4b1221b pairs/zh-ru.yaml
|
||
```
|
||
|
||
⚠ **Бинарь НЕ ТОТ, что вёз холодный прогон** (`e6f872df…`, main @ `065d8ac`). Между ними уехали
|
||
`volume.go` (+118), `terminologist.go` (+102), `snapshotdiff.go` (новый), `rebill.go`, `status.go`;
|
||
в `stagerun.go` изменился ТОЛЬКО текст ошибки снапшот-гарда (проверено `git diff` — формула
|
||
`max_tokens` не тронута), а `snapshot.go`, `ledger.go` и `models.yaml` не тронуты вовсе. Пере-сборка
|
||
из `065d8ac` потребовала бы `checkout` в чужом рабочем дереве — запрещено каноном. Расхождение
|
||
названо здесь, а не скрыто.
|
||
|
||
## 5. КОЭФФИЦИЕНТ ВОССТАНОВЛЕНИЯ РАЗМЫШЛЕНИЯ
|
||
|
||
`R̂ = completion_tokens − 0.3644 · len(сырой response_text попытки)` — **0.3644 токена/знак**, запинено.
|
||
Границы (из плана §3, названы до покупки): CJK в выходе ломает оценку и завышает `R̂`; при `R̂ < ~700`
|
||
относительная ошибка 20–70% и о величине таких клеток вывод не делается; берётся СЫРАЯ строка
|
||
попытки, не `sanitized_export`; типичная ошибка ~3%, худшая клетка 5.3%.
|
||
⛔ **У референса `glm-5` `R̂ = 0` ПО ПОСТРОЕНИЮ**, а не по формуле.
|
||
|
||
**Дыра прибора подтверждена на данных:** в базе холодного прогона `sum(reasoning_tokens>0) = 0` при
|
||
68 строках; положительный контроль — 38 строк с непустым `completion_tokens`.
|
||
|
||
## 6. ДЕНЬГИ — правило запинено ДО чисел
|
||
|
||
* **Санкция владельца: $9.50 в ПИКОВЫХ терминах.** Сессией не поднимается. Гард ⇒ стоп и вопрос.
|
||
* **Пояс базового прогона: `--ceiling-usd 0.60`.**
|
||
* **Потолок руки** `i` = `base_факт + w_i · (9.50 − base_факт)`, веса пропорциональны ожидаемой цене
|
||
клетки (§6 плана: ∅ $0.09, low $0.05, референс $0.02):
|
||
|
||
| рука | `w` | смысл |
|
||
|---|---|---|
|
||
| `p7-off`, `p9-off` | 0.3000 каждая | дороже всех: без ручки думают больше |
|
||
| `p7-low`, `p9-low` | 0.1667 каждая | |
|
||
| `glm-off` | 0.0667 | референс, теряется первым |
|
||
|
||
Сумма весов **1.0000**, поэтому `base + Σ(потолок_i − base) = $9.50 РОВНО` при любом фактическом
|
||
`base`. Это и есть механизм, которого у леджера нет: он считает потолок по `book_id`, а `spend`
|
||
лежит ВНУТРИ проектной базы, и каждая из пяти копий несёт базовый расход под тем же `book_id`.
|
||
* **Агрегат ведётся вручную после КАЖДОГО юнита:** `израсходовано = база + Σ(копия − база)`.
|
||
* ⚠ `--ceiling-usd` сравнивается с **накопленным** расходом книги, а не с расходом прогона
|
||
(`cmd/tmctl/main.go:260`) ⇒ в него кладётся «база + доля», а не «доля».
|
||
* ⚠ `--ceiling-usd` перекрывает **только** `book_usd`; `day_usd` берётся из `book.yaml`
|
||
(`stagerun.go:496`) ⇒ дневной потолок задан в каждой руке как `book_usd + $1.00`.
|
||
|
||
**⭐ ПОРОГ, ОБЪЯВЛЕННЫЙ ДО ПРЕД-ПОЛЁТА, чтобы не выбирать его после чисел.** Цена клетки `low` —
|
||
единственное число сметы без источника (движковых редакторских вызовов на `low` не существует).
|
||
В репозитории есть независимый замер, которого план не использовал: `docs/experiments/23-editor-tier.md:7139`,
|
||
арм `RNL` 30.08 на `low` — `$0.056695` за вызов, то есть ближе к «худшему» сценарию плана ($0.065),
|
||
чем к центральному ($0.04). ⇒ **Решение: пред-полётная клетка `low` ≤ $0.065 — иду дальше** (это
|
||
худший сценарий §6 плана, потолок его покрывает ценой потери 1–2 юнитов, что план называет штатным
|
||
исходом). **> $0.065 — СТОП и вопрос владельцу**, потому что выше в замороженной смете сценария нет.
|
||
|
||
## 7. ОПРЕДЕЛЕНИЕ «ДОСТАВЛЕНО» — объявляется ДО чисел, вместе с проверкой устойчивости
|
||
|
||
`delivered` меряется на **отгружаемом** тексте (`checkpoints.response_text` по `chunk_status.final_hash`;
|
||
`final_hash` может быть синтетическим `tm-sanitized-v1:<sha>` и тоже лежит в `checkpoints` — проверено).
|
||
|
||
* **delivered = 0** ⟺ диспозиция `skipped`, ИЛИ `final_hash` не резолвится, ИЛИ отгружаемый текст не
|
||
проходит $0-предикат: доля кириллицы среди букв < 0.99 либо в тексте есть CJK.
|
||
* **иначе** `delivered` = длина отгружаемого текста в знаках.
|
||
|
||
⚠ **Почему НЕ «flagged ⇒ 0»:** в холодном прогоне 1 из 3 редакторских юнитов — `sanitizer_stripped`
|
||
(CJK-утечка, санитайзер её вырезал, текст ОТГРУЖЕН, 6048 знаков). По правилу «flagged ⇒ 0» гард
|
||
«>20% пустых ⇒ прибор отказывает» сработал бы от санитайзера, а не от предмета замера. Флаги при этом
|
||
не теряются — они целиком идут в E5, разделённые по механизму (санитайзер / CJK / обрыв по длине).
|
||
**Строгий вариант (`flagged ⇒ 0`) считается ВСЕГДА и печатается рядом как заранее объявленная проверка
|
||
устойчивости.**
|
||
|
||
## 8. ПРАВИЛО РЕШЕНИЯ — из §4 плана, здесь не пересматривается
|
||
|
||
`p<0.05` двусторонне ⇒ эффект есть, величина = медиана Ходжеса–Лемана с 95% ДИ. Иначе ⇒
|
||
**«НИЖЕ РАЗРЕШЕНИЯ ЗАМЕРА»**, и это НЕ «эффекта нет». Полоса [0.8; 1.25] — **описательная**, решения
|
||
не несёт. Нули (ничьи от цензуры) СОХРАНЯЮТСЯ: `zero_method='pratt'` (умолчание `wilcox` их
|
||
выбрасывает — проверено исполнением на `scipy 1.18.0`). ДИ Ходжеса–Лемана написан руками: у
|
||
`wilcoxon` в этой версии интервала нет (проверено — у результата только `statistic`/`pvalue`/`count`/`index`).
|
||
Цензура на потолке — симметрично, по §4; величина под цензурой печатается со знаком **«≥»**.
|
||
|
||
## 9. ⛔ ОТСТУПЛЕНИЯ ОТ ЗАМОРОЖЕННОЙ ПРОЦЕДУРЫ — предъявляются, а не правятся молча
|
||
|
||
План §10 требует: «если исполнение покажет, что что-то из замороженного неверно — это НАХОДКА,
|
||
которая записывается и предъявляется». Ниже — все, найденные ДО первой покупки.
|
||
|
||
| # | § | что в плане | что на самом деле | что делаю |
|
||
|---|----|---|---|---|
|
||
| 1 | §9.2 | конфиги рук в `$B/arms/` | `LoadPair` ищет пар-слой в `<каталог PIPELINE-файла>/pairs/` (`config/pipeline.go:821`), а отсутствие файла = `(nil, nil)` **тихо** (`config/pair.go:55-64`). ⚠ **ПЕРВОНАЧАЛЬНАЯ ФОРМУЛИРОВКА ЭТОЙ СТРОКИ БЫЛА ПРЕУВЕЛИЧЕНА И СНЯТА — см. §9-КВАТЕР** | конфиги рук лежат в `$B/` рядом с единственным `$B/pairs/`; в `$B/arms/` только `.book.yaml` и `.db` — решение остаётся, но обосновано отсутствием дрейфа двух копий, а не опасностью |
|
||
| 2 | §9.3 | `--ceiling-usd 1.20` на базовый прогон | правило §9.0 п.1 — «чуть выше ожидания ЧЕРНОВОЙ волны»; ожидание, пере-снятое с леджера: не-edit расход $0.436110−$0.214865 = $0.221245 на 28 174 знака ⇒ ×1.6866 = $0.373 + эскалация ≈ **$0.45**. Зазор при поясе 1.20 = $0.75; резервация одной edit-клетки ≈ 16000·3.96/1e6 + 5000·1.32/1e6 ≈ **$0.070** (⚠ расчёт, не замер: потолок вывода pro = флор 16000) ⇒ в зазор влезает **порядка десяти** редакторских юнитов, а купленная в базе редактура необратима | пояс **0.60**. Асимметрия в правильную сторону: перелёт стоит перекупки, недолёт — бесплатного resume (код 4, черновики целы). ⚠ Первая же резервация черновика замерена Ш1: **$0.012052** — оценка вчетверо выше фактической цены чанка ($0.0034 по холодному прогону), потому что леджер букирует пик |
|
||
| 3 | §9.3 | `rc=$?` после `\| tee` | в сниппете плана **нет `set -o pipefail`**, а без него `$?` возвращает код `tee` ⇒ проверка `[ $rc -eq 4 ]` **не сработает никогда**. Проверено исполнением: без `pipefail` `$?` = 0, с `pipefail` = 4, `${PIPESTATUS[0]}` = 4 в обоих случаях | `${PIPESTATUS[0]}` (правда независимо от `pipefail`) |
|
||
| 4 | §9.3 | останов цикла по `grep -q 'VOLUME CEILING:'` | строка печатается при `res.Volume != nil`, то есть на **КАЖДОМ** прогоне с `--max-units` (`cmd/tmctl/render.go:130`) ⇒ `break 2` рвал бы цикл после первой же клетки | цикл ограничен **`N=20` из пре-рега**, а не выводом; строка «never been delivered» лишь ПЕЧАТАЕТСЯ как признак «рука закончена». Останавливают цикл: код 4, код 3, неожиданный код, рассинхрон рук и агрегат $9.50 |
|
||
| 5 | §9.3 | `--config $B/arms/$arm.yaml` при том, что §9.2 зовёт `$arm.yaml` копией **pipeline** | `translate` грузит **book.yaml** | пять `book.yaml` рук, различающиеся ровно тремя полями (`pipeline`, `project_db`, `ceilings`) |
|
||
| 6 | §9.1 | `day_usd` не упомянут | `--ceiling-usd` его не перекрывает; наследованный из образца `day_usd: 1.00` остановил бы руку `∅` посреди пачки | `day_usd = book_usd + $1.00` в каждой руке |
|
||
| 7 | §5.3 | «мина вооружается ТУМБЛЕРОМ, а уровни эффорта её не вооружают» | `00-provider-quirks.md:123`: «`effort:"low"` **ПЕРЕ-ВООРУЖАЕТ** эхо-мину… защита деградирует НЕПРЕРЫВНО с эффортом»; :132 — off 4/20 против low 3/20, на N=20 неразличимо | формулировка снята как неверная; критерий E5 плана опасность уже несёт, поэтому дизайн не меняется |
|
||
| 8 | §4 | ковариатная модель `log R̂ ~ effort + prompt + log(len_draft) + (1\|unit)` как проверка устойчивости E1/E3 | **не может быть проверкой устойчивости E1/E3**: `len_draft` — величина УНИТ-УРОВНЕВАЯ (все четыре руки редактируют ОДИН черновик — это и есть блокировка трудности), а в сбалансированном внутри-юнитном дизайне юнит-уровневая ковариата НЕ МЕНЯЕТ оценок усилия и промпта ПО ПОСТРОЕНИЮ. Сам наклон длины при этом оценим — он считается отдельно | считаю руками обе величины, которые она дала бы: (1) МНК контраста по `log(len_draft)` — внутри-юнитная устойчивость; (2) МНК среднего по юниту `log R̂` по `log(len_draft)` — это и есть коэффициент длины в сбалансированном дизайне. `statsmodels` **не установлен**; ⚠ причина НЕ «нет сети» (сеть есть, колесо под cp314 существует — проверено), а вырожденность модели плюс риск правки общего venv при живых параллельных сессиях |
|
||
| 9 | §9.6 | «`n` = сколько получится» | `tmctl manifest` бесплатен и даёт `units_total` **до** первой покупки | `n = 20` запинено здесь |
|
||
|
||
| 10 | §9.3 | у рук флага `--verify-bank` нет | флаг оставлен и в руках **намеренно**: в копиях банк уже предъявлен базовым прогоном, `hasUnpresentedCluster` вернёт false (`mining.go:222-230`), и движок напечатает «every cluster already presented — continuing». Это $0-улика состояния банка и страховка: если рука вдруг соберёт НОВЫЙ кластер, она встанет кодом 3 громко, а не поедет с другим банком молча | флаг подаётся всем пяти рукам; отступление названо здесь |
|
||
|
||
## 9-КВАТЕР. ⛔ МОЯ СОБСТВЕННАЯ ОШИБКА, СНЯТАЯ ИСПОЛНЕНИЕМ ДО ФРИЗА
|
||
|
||
**Класс: чтение кода — своё и агента-контролёра — принято за факт о мире.** Ровно тот класс, которым
|
||
предыдущая сессия ошиблась одиннадцать раз (§8 плана). Записано здесь, потому что фриз не должен
|
||
нести преувеличенную находку.
|
||
|
||
**Что я утверждала:** «руки в `$B/arms/` без своего `pairs/` ТИХО потеряли бы калибровку нарезки,
|
||
это сдвинуло бы `segmentationSnap` ⇒ черновой снапшот ⇒ перекупка всех черновиков ×5».
|
||
|
||
**Что показало исполнение (два независимо достаточных опровержения, оба за $0):**
|
||
|
||
1. **Без каталога `pairs/` прогон ПАДАЕТ ГРОМКО, а не молча.** `prompts_root` откатывается на
|
||
несуществующий каталог, и загрузчик отказывает ещё до всякой нарезки:
|
||
```
|
||
tmctl: config .../nopairs/pipeline.yaml:
|
||
- gates.terminology is enabled but its role prompt is missing — expected .../prompts/zh-ru/terminologist.md
|
||
- gates.terminology.classify_types is on but its prompt is missing — expected .../prompts/zh-ru/classifier.md
|
||
RC=10 (отказ, $0, ни одного вызова)
|
||
```
|
||
2. **Даже с пар-слоем БЕЗ блока `segmentation` снапшот НЕ ДВИГАЕТСЯ.** Дженерик-умолчания в
|
||
`internal/config/pipeline.go:895-905` — это `1797 / 3200 / 1.1978 / 0.3852`, то есть **ровно те же
|
||
числа**, что несёт `pairs/zh-ru.yaml`. Прогон с вырезанным блоком дал снапшот
|
||
`8d5721f6559624d9…` — побайтно тот же, что и полный конфиг.
|
||
|
||
**Что остаётся верным:** механизм тихого отката у `LoadPair` реален, и для пары, чья калибровка
|
||
ОТЛИЧАЕТСЯ от дженерик-умолчаний, ловушка сработала бы. Для zh-ru — нет. Решение держать все пять
|
||
конфигов рук рядом с одним `pairs/` остаётся в силе, но его довод теперь честный: **оно исключает
|
||
расхождение двух копий пар-слоя**, а не спасает от перекупки, которой здесь не было.
|
||
|
||
## 9-ТЕР. ТРИ РЕШЕНИЯ ПРИБОРА, ОБЪЯВЛЕННЫЕ ДО ЧИСЕЛ
|
||
|
||
Найдены верификацией собственной работы (агент-контролёр + мои пере-проверки), исправлены ДО фриза.
|
||
|
||
**(а) ⛔ E5 меряет эхо по СЫРОМУ ответу попытки 0, а не по отгружаемому тексту.** Первая редакция
|
||
прибора считала CJK по отгружаемому — а санитайзер эхо ВЫРЕЗАЕТ, и эндпойнт, блокирующий любую
|
||
рекомендацию, был слеп ровно к своему предмету. Улика, снята командой на базе холодного прогона:
|
||
|
||
```
|
||
ЮНИТ флаг CJK в отгруженном | CJK в СЫРОМ ответе попытки 0
|
||
(1,0) sanitizer_stripped 0 | 10
|
||
(1,1) — 0 | 0
|
||
(2,0) — 0 | 0
|
||
```
|
||
|
||
Колонка по отгруженному остаётся ВТОРОЙ: она отвечает на другой вопрос — что увидел читатель.
|
||
Это важно вдвойне, потому что `00-provider-quirks.md:121` прямо говорит: эхо-безопасность
|
||
РЕДАКТОРСКОЙ роли на `pro`@`low` по плотному CJK **не мерена ни разу** (пять чистых хопов 31.08 —
|
||
роль ПЕРЕВОДЧИКА). ⇒ этот замер и есть первый такой контроль в проекте, и слепой E5 обнулил бы его.
|
||
|
||
**(б) ⚠ ПЕРЕКОС ПОРЯДКА ПРИ ЗАПИНЕННОМ СИДЕ — посчитан до чисел, сид НЕ трогается.** Выпавшая
|
||
перестановка на n=20 несимметрична:
|
||
|
||
```
|
||
первой клеткой юнита: p7-low 10 · p9-low 6 · p9-off 3 · p7-off 1
|
||
пара P7: low раньше off в 15 юнитах из 20 пара P9: 9 из 20
|
||
```
|
||
|
||
Первая клетка юнита не бьёт префикс-кэш и потому дороже примерно на 6000·($1.32−$0.044)/1e6 ≈
|
||
**$0.0077**. ⇒ E2 у пары P7 систематически наклонён ПРОТИВ `low`. Сид — часть пре-рега и не
|
||
меняется; вместо этого E2 печатается в ЧЕТЫРЁХ заранее объявленных вариантах: попытка 0 ×
|
||
фактическая цена (основной) · итог юнита × фактическая цена · попытка 0 × строгое `delivered` ·
|
||
попытка 0 × **кэш-независимая цена** (весь вход по полной ставке — снимает перекос целиком).
|
||
На E1 это не влияет вовсе: `R̂` от кэша не зависит.
|
||
|
||
**(в) ⚠ ДЛИНА ВХОДА ЮНИТА СОБИРАЕТСЯ ИЗ ЧАНКОВ ПО МАНИФЕСТУ.** Юнит редактуры и чанк черновика —
|
||
разные единицы: в этом стенде 20 юнитов на 35 чанков, и **у 15 юнитов из 20 `chunk_count > 1`**.
|
||
Ключ `(глава, индекс)` у них СОВПАДАЕТ, поэтому «взять первый чанк» не дало бы ни ошибки, ни
|
||
пустоты — только занижённую ковариату у трёх четвертей выборки. Прибор суммирует
|
||
`first_chunk_idx … first_chunk_idx+chunk_count−1`; неполный юнит становится `None`, а не полусуммой.
|
||
Проверено прямым тестом функции (сценарий 0 контроля).
|
||
|
||
## 9-БИС. ⭐ ПРОВОДНАЯ УЛИКА ЕСТЬ — план утверждал обратное
|
||
|
||
План §3 «Дыра 2»: «У движка нет проводного артефакта — стадийный лог эффорт не печатает… Оба
|
||
свидетеля косвенные; побайтной улики у движка нет». **Это неверно, и опровержение бесплатно.**
|
||
|
||
`internal/obs/logging.go:72` `LogLLMExchange` пишет **сырое тело запроса и ответа** на уровне DEBUG,
|
||
когда включены `LOG_LLM_BODIES=1` И `LOG_LEVEL=debug`. Вызывается из `internal/llm/httpllm.go:415` —
|
||
это и есть OpenAI-совместимый путь, по которому едут и `deepseek`, и `zai`. Тело режется до 32 768 Б
|
||
**с сохранением ОБОИХ концов** — это и делает улику доступной: Go маршалит `map` с сортировкой ключей,
|
||
и `reasoning_effort` ложится ПОСЛЕ длинного `messages`, то есть в ХВОСТ тела, который обрезание сохраняет. Логируются ТОЛЬКО тела —
|
||
никогда URL и никогда заголовки, поэтому ключ утечь не может (комментарий там же, :70).
|
||
|
||
⇒ **Пред-полёт идёт с включённым каналом**, и в пре-рег ложится побайтная улика: у рук `low` в теле
|
||
стоит `"reasoning_effort":"low"`, у рук `∅` этого ключа НЕТ, у референса стоит
|
||
`"thinking":{"type":"disabled"}`. Это прямо исполняет требование промта §7.1 «прочитай вслух тело
|
||
запроса каждой руки». Пачка идёт уже БЕЗ канала — он нужен один раз, а объём логов не бесплатен.
|
||
|
||
⚠ Новой экспозиции текста это не создаёт: логи ложатся в `$B/logs/` внутри каталога книги, где сам
|
||
текст книги уже лежит.
|
||
|
||
**Второе бесплатное подтверждение, которое дал сам движок.** На `manifest` конфига `glm-off` он
|
||
напечатал предупреждение, а на четырёх руках креста — нет:
|
||
|
||
```
|
||
level=WARN msg="a stage sends the SOURCE text to a model whose wire SUPPRESSES thinking —
|
||
the ratified echo zone (D19.1 point 2: reasoning-off + dense CJK is a property of the model
|
||
class, not a vendor quirk)... it costs a paid call per hit" stages=edit→glm-5 source_lang=zh
|
||
```
|
||
|
||
То есть движок сам различает: у `glm-5` при `off` размышление ВЫКЛЮЧЕНО, а у `deepseek-v4-pro` при
|
||
`off` — нет (ключ просто не отправляется, thinking остаётся включённым). Ровно то различие, на
|
||
котором стоит дизайн, — предъявлено движком, а не конспектом.
|
||
|
||
## 10. ЧТО ФРИЗ НЕ ПОКРЫВАЕТ
|
||
|
||
Сигнатуру Δ`prompt_tokens` — её нельзя было задать заранее (единственное известное значение −79 снято
|
||
на английской паре и на риге). Пред-полёт её **замеряет**, ФРИЗ №2 её **пинит**, и только после этого
|
||
она становится гейтом с допуском **±2 токена** и правилом «>20% юнитов вне допуска ⇒ проба
|
||
аннулируется».
|
||
|
||
## 11. ПРИБОР ПРОВЕРЕН ИСПОЛНЕНИЕМ, А НЕ САМООТЧЁТОМ
|
||
|
||
`eval/dovodka/proverka_pribora.py` строит синтетические проектные базы той же схемы с ЗАРАНЕЕ
|
||
ИЗВЕСТНЫМ ответом и прогоняет по ним настоящий `chetyre.py`. Прямой тест функции + девять
|
||
сценариев, всё зелёное:
|
||
|
||
```
|
||
0. сборка длины входа юнита из чанков → 350 / 7 / 24 / None (наивная дала бы 100 — МОЛЧА)
|
||
1. эффект ×2 заложен → прибор нашёл, Ходжес-Леман ×0.512 против истины ×0.500 (код 0)
|
||
2. эффекта нет → «НИЖЕ РАЗРЕШЕНИЯ ЗАМЕРА», не «эффекта нет» (код 0)
|
||
3. рука вся пустая → ⛔ ПРИБОР ОТКАЗЫВАЕТ (код 2)
|
||
4. ось схлопнулась → ⛔ ПРИБОР ОТКАЗЫВАЕТ, назвав prompt_sha256 (код 2)
|
||
5. треть ∅ цензурирована → посчитал и объявил величину нижней границей (код 0)
|
||
6. 19 строк-повторов на клетку → взял НАСТОЯЩИЙ вызов, ×0.462 против истины ×0.500 (код 0)
|
||
7. сигнатура сломана у 40% юнитов → ⛔ ПРОБА АННУЛИРОВАНА (код 2)
|
||
8. эхо ЗА САНИТАЙЗЕРОМ → E5 видит CJK@сырой=4 при CJK@отгруженном=0 (код 0)
|
||
9. баз нет вовсе → ⛔ ПРИБОР ОТКАЗЫВАЕТ, а не печатает нули (код 2)
|
||
```
|
||
|
||
⚠ Сценарии 3, 4, 7 и 9 ждут от прибора ОТКАЗА — это не подгонка под зелень, а проверка того, что
|
||
прибор умеет говорить «нет».
|
||
|
||
⚠ Сценарий 6 проверяет защиту, которой в первой редакции прибора НЕ БЫЛО, и она куплена чтением
|
||
данных, а не догадкой: интерливинг гоняет каждую руку 20 раз с `--max-units 1`, и каждый прогон
|
||
дописывает в `request_log` строку-ПОВТОР уже оплаченной клетки — `tm_hit=1`, все токены и цена
|
||
НУЛЕВЫЕ, но `request_hash` тот же, то есть она соединяется с тем же чекпойнтом и несёт `attempt=0`.
|
||
Проверено на базе холодного прогона: 29 таких строк из 68, у всех нули. Прибор выбирает настоящий
|
||
вызов явно (`tm_hit=0`), а не по порядку `id`.
|
||
|
||
Команда: `./eval/.venv/bin/python eval/dovodka/proverka_pribora.py`
|
||
|
||
**Цикл интерливинга `eval/dovodka/pachka.sh` проверен тем же способом** — на ПОДДЕЛЬНОМ `tmctl`,
|
||
который печатает то же, что настоящий, и продвигает БД руки. Проверялись не успешные ветки (они
|
||
очевидны), а **отказные**:
|
||
|
||
| подделка | что обязан сделать цикл | получено |
|
||
|---|---|---|
|
||
| рука `p9-low` не продвигается (оборванный вызов без чекпойнта) | заметить рассинхрон и встать | ⛔ «РУКА p9-low РАЗЪЕХАЛАСЬ: 0 вместо 1», **код 5** |
|
||
| движок вернул код 4 | стоп и вопрос владельцу, добор запрещён | ⛔ код **4** |
|
||
| движок вернул код 3 в РУКЕ (банк уже предъявлен базой — так быть не должно) | стоп | ⛔ код **3** |
|
||
| копия несёт НЕ базовый расход (сделана не из того бэкапа) | не начинать: агрегат соврал бы | ⛔ «КОПИЯ p9-low НЕСЁТ $0.61 ВМЕСТО БАЗОВЫХ $0.45», код **1** |
|
||
| рука купила ДРУГОЙ юнит при том же ЧИСЛЕ юнитов | заметить по НАБОРУ КЛЮЧЕЙ | ⛔ «эта рука `51:0` · эталон `1:0`», код **5** |
|
||
|
||
⚠ Инвариант синхронности рук существует потому, что блокировка трудности держится на «k-я клетка —
|
||
ОДИН И ТОТ ЖЕ юнит у всех пяти рук». Оборванный вызов сдвинул бы одну руку на юнит назад, и дальше
|
||
руки сравнивали бы РАЗНЫЕ чанки — **молча, без единой ошибки**. Проверка после каждой клетки:
|
||
сверяются НАБОРЫ КЛЮЧЕЙ `chapter:chunk_idx` всех пяти рук, а не только их число — счётчик совпал бы
|
||
и у рук, купивших разные юниты. База для агрегата берётся из ФАЙЛА БЭКАПА, из которого сделаны копии,
|
||
а не с живой базовой БД: иначе любое касание базы сдвинуло бы вычитаемое молча.
|
||
|
||
## 12. ЧЕГО В ЗАМЕРЕ НЕТ НАМЕРЕННО
|
||
|
||
Судейства качества (качество при сниженном усилии — вне скоупа; только $0-гейты и ось безопасности
|
||
E5) · калибровки ставки платформы · правок `models.yaml`, capabilities, Go, боевого `pipeline-c1.yaml` ·
|
||
смены модели, черновика, дифф-контракта · флага `--resnapshot` — **никогда**.
|