docs(router-mentor): A1 judge gate2 activation note (implementation-specific)

This commit is contained in:
Дмитрий
2026-06-09 08:55:33 +03:00
parent a48eb6fe1c
commit d96f7ea2eb
@@ -0,0 +1,51 @@
# A1 — Активация судьи М4 на Гейт-2 (под фактически собранный код)
**Дата:** 2026-06-09 · **Эпик:** «роутер-наставник» · **Ветка:** `worktree-brainrepo` · commit-not-push.
**Код A1:** коммиты `0c6f084f..e8958155` (+ spec/plan `cfca7ecf`). Реализация — `tools/enforce-judge-gate.mjs`.
Это **implementation-specific** дополнение к общему runbook `2026-06-09-router-mentor-activation-A1-A6-A7.md` §A1.
> До твоих рубильников хук **инертен, $0** (нет флага/ключа → `judgeGateMode==='inert'` → allow без прогона).
---
## Что включается (твои 🔴-шаги по порядку)
1. **HMAC-ключ судьи** в keychain (нужен, чтобы `judgeActive` стал true):
- service `router-mentor-judge`, account `default` (точно — `tools/judge-key-config.mjs`).
- назначение — подпись под-прогонов судьи (отдельный домен от транспорта). Без него судья инертен.
2. **Транспорт-ключ** `ROUTER_LLM_KEY` (env, **тот же, что у классификатора**) — уже есть, если работает router-classifier.
- **Важно (Δ-C):** если флаг+HMAC включены, но `ROUTER_LLM_KEY` отсутствует — судья НЕ блокирует всё подряд,
а уходит в **degraded-allow + WARN** (`judge_unavailable` в логе). Это специально (урок v4-over-block).
3. **Флаги** (env, строго):
- `ROUTER_MENTOR_JUDGE_ENABLED=1` (ровно `1`; иначе inert).
- `ROUTER_MENTOR_JUDGE_MODE=shadow` (дефолт; опечатка → безопасный shadow). Block — отдельным шагом ниже.
4. **Регистрация ОБЁРТКИ** `enforce-judge-gate` в `.claude/settings.json` как **PreToolUse**, matcher `Write`
(Гейт-2 судит только запись плана; хук сам отфильтрует не-план → allow). Команда: `node tools/enforce-judge-gate.mjs`.
- Регистрировать **обёртку**, не движок (`judge-engine`/`judge-orchestrator` без `main()`/транспорта — у них нет рубильника $0).
- Зеркаль формат существующих PreToolUse `enforce-*` записей в settings.json.
5. **Перезапуск** сессии.
## ✅ Проверка (shadow, 1-2 дня)
- Создай план через `Write` в `docs/superpowers/plans/*.md` (или сделай любой) → судья прогонится, но **НЕ заблокирует**.
- Лог вердиктов: `~/.claude/runtime/judge-verdicts.jsonl` (читаешь ты — runtime мне закрыт):
- `{"kind":"verdict","functionName":"gate2","decision":"GO|NO-GO",...}` — судья отработал.
- `{"kind":"judge_unavailable",...}` — судья не смог (нет `ROUTER_LLM_KEY` / транспорт упал). Если их много — проверь `ROUTER_LLM_KEY`.
- **На что смотреть:** нет ли ложных NO-GO на нормальных планах (over-block-калибровка, как у v4-судьи). На обычные тулы
(не-Write / не-план) судья молчит и денег не тратит ($0).
## Перевод в боевой
- После чистого shadow: `ROUTER_MENTOR_JUDGE_MODE=block` → перезапуск.
- Теперь NO-GO на запись плана **блокирует** запись (Гейт-2 приёмка). degraded-allow (судья недоступен) по-прежнему пропускает.
## ↩ Откат
- `ROUTER_MENTOR_JUDGE_MODE=shadow` (если был block) ИЛИ снять `ROUTER_MENTOR_JUDGE_ENABLED` → inert, $0.
## Границы A1 (что НЕ входит — следующие фазы)
- **A6** (журнал М1) и **A7** (наставник М3 live-wiring) — отдельно; A7 требует живых A1+A6 (см. общий runbook).
- A1 судит **только план реализации (Гейт-2) на Write**. Гейт-1 (спека) / Гейт-3 (результат) / A2 — не в A1.
- **Спенд:** inert=$0 / shadow=метеренный (LLM-вызов за каждую запись плана) / block=метеренный.
- **Отложено (documented):** дедуп по content-hash + per-session budget-cap (Write-only уже ограничивает частоту).