pre-step gate: prestep='none'|'progress' (default bit-identical), refuse the similarity step BEFORE spending an evaluation when it promises less progress than bisection — two lengths already in hand, no new constant; R1-R4 pinned by tests/test_prestep_gate.py (6 green); the gate grid writes to its OWN sweep_gate.json

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
vvs
2026-09-20 23:12:34 +01:00
co-authored by Claude Opus 5
parent be10fc0b22
commit 0617243ed4
5 changed files with 215 additions and 10 deletions
+69
View File
@@ -0,0 +1,69 @@
# PREREG — предшаговый гейт: похожесть как ОТКАЗ до шага, а не масштаб внутри шага
Составлено до реализации. Основание — измерение `explain_chandrupatla.py` (лог
`results_explain_chandrupatla.txt`, разбор в `FINDINGS_logarithmic.md` §3): Chandrupatla принимает
свою модель лишь в **28 %** шагов, его гейт стоит **ноль** вызовов, а ветвь отказа снимает половину
скобки; наш сторож ремонтирует **77.5 %** вызовов, и на `fun8`/`fun9` мы опускаемся до **0.92**
половинок на вызов — хуже деления пополам. Качество пробы: **2.310** против **1.422**.
**Гипотеза:** дело не в форме функции похожести, а в **месте её чтения**. Похожесть, прочитанная ДО
шага и решающая «доверять ли модели здесь», стоит ноль; прочитанная ВНУТРИ шага как масштаб — требует
сторожа, а сторож платит вызовом.
---
## 1. Что именно добавляется (и почему это не новая константа)
**Важно, что наша причина ремонтов ДРУГАЯ, чем у Chandrupatla.** Наш шаг
`(1 − S(|f|/σ))·(far − x)` при `0 ≤ S ≤ 1` **никогда не выходит за скобку** — то есть перескок нам не
грозит; сторож вмешивается, когда шаг слишком **короткий** и прогресс мал. Значит и гейт должен
спрашивать не «не выйдет ли проба за скобку» (вопрос Chandrupatla для его модели), а:
> **обещает ли этот шаг прогресс не хуже, чем деление пополам?**
Обе длины известны ДО вызова `f`: длина шага `|step|` и длина шага в середину `|½(A+B) − x|`.
Сравнение двух имеющихся длин — не константа и не подгонка; порога нет, есть неравенство.
**Режим:** `prestep="none"` (по умолчанию — опубликованное поведение побитово) и
`prestep="progress"` (гейт включён). Если гейт отказал, шаг **заменяется** на деление пополам, то есть
тот же один вызов `f` тратится на гарантированное снятие половины скобки.
**Чего НЕ делаем:** не переносим полосу `1−√(1−ξ) < φ < √ξ` в наш метод. Она выведена для обратной
квадратичной интерполяции из условия «проба не выйдет за скобку»; у нашего шага этого условия нет, и
взятая напрокат область была бы скрытой константой чужого вывода.
## 2. Предсказания и фальсификаторы
| # | Предсказание | ФАЛЬСИФИКАТОР → вывод |
|---|---|---|
| **P1** | доля ремонтов на CHA падает с 77.5 % до **≤40 %** | >60 % → гейт не бьёт в механизм, объяснение §3 неверно как рецепт |
| **P2** | цена на CHA падает ниже нашей текущей **2073** (та же конфигурация `ratio.derived3.credit`) | не падает → отказ дешевле ремонта не оказался, гипотеза о месте чтения не подтверждена |
| **P3** | цена на APS-154 **не растёт** (по-наборный лучший остаётся ≤ **2806**) | растёт → тот же трейд, что убил пять предыдущих попыток; гейт отвергается |
| **P4** | гарантия `2⌈log₂(w/xtol)⌉+3` не нарушена: `over2x = 0` во всех конфигурациях | нарушена → закрытие немедленно |
| **P5** | качество пробы на CHA растёт с 1.422 к уровню **≥2.0** половинок на вызов | <1.7 → прирост есть, но не тот порядок; заявлять «как Chandrupatla» нельзя |
**Правило остановки:** P3 или P4 ложны ⇒ режим не принимается вовсе. P1 и P2 ложны ⇒ объяснение
остаётся верным как **описание** Chandrupatla, но как **рецепт** для нашего метода — опровергнуто, и
это пишется прямо.
## 3. Протокол (тот же, что у статьи)
154 задачи Alefeld–Potra–Shi + 45 Чандрупатлы; цена — вызовы `f`; провал списывается полным бюджетом;
граница `2×` проверяется на каждом решённом прогоне; конфигурация фиксируется выводом ДО того, как
смотрят в рейтинг. Числа только с **Linux**. Свип пишется в свой файл (`sweep_gate.json`), чтобы
`sweep_full.json`, против которого сверяется статья, остался нетронутым.
Сравнение ведётся **по-наборно** и **внутри семейства сторожей, несущих гарантию** — иначе сравниваются
разные конфигурации (эта ошибка уже допущена 2026-09-20 и исправлена).
## 4. Гейты реализации (тесты ДО рейтинга)
| # | Условие | Проверка |
|---|---|---|
| **R1** | `prestep="none"` даёт побитово прежний результат | тест на равенство кортежей возврата на наборе задач |
| **R2** | в гейте нет ни одной выбранной константы | грепом по исходнику: только `0.0`, `0.5` (середина скобки — определение деления пополам), `1.0` |
| **R3** | отказ гейта не стоит вызова `f` | тест: число вызовов при включённом гейте не превышает число шагов + 2 |
| **R4** | счётчик `stats['pre_refused']` считает отказы гейта отдельно от ремонтов сторожа | тест на обоих счётчиках |
**Дисциплина:** аудит после правки и до запуска; смоук ×2 локально; тяжёлое — на сервер
`setsid nohup` с логом; замороженная копия скрипта; числа показываются немедленно.