Files
portal/docs/superpowers/2026-06-16-mentor-empty-recommendation-bug.md
T

70 lines
5.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Баг: наставник GO с пустым `recommendation` → судья не вызывается (`no_mentor_go`)
**Дата:** 16.06.2026. **Где:** машинерия стены «роутер-наставник», оркестратор
`enforce-mentor-then-judge` (наставник → судья). **Severity:** блокирующий печать — план с
чистым GO не опечатывается. **Куда:** проект **claude-brain** (управляющий слой).
## Симптом
При записи опечатываемого плана наставник (Agent mentor, модель `deepseek-v4-pro`)
возвращает чистый GO без замечаний:
```json
{ "plan_points_addressed": [...], "reasoning": "...", "recommendation": "", "confidence": 0.95, "decision": "GO" }
```
Оркестратор применяет проверку-содержательности вердикта, видит **пустой слот
`recommendation`** и помечает вердикт несодержательным → `no_mentor_go` → **судья НЕ
вызывается** → план не печатается. В логе:
`несодержательный вердикт: пустые слоты [recommendation]` + `⏭ пропуск (no_mentor_go)`.
## Корень
Проверка-содержательности (введена M4-аудитом: «слот вердикта обязан быть непустой
строкой, `{}` больше не содержателен») применяется **одинаково** к GO и NO-GO. Для NO-GO
непустой `recommendation`/objection логичен. Для **GO** пустой `recommendation` — нормальное
состояние (плану нечего рекомендовать), но проверка его отбраковывает → валидный GO теряется
→ судья пропускается → печать не встаёт. Дефект делает невозможной печать «идеального» плана,
к которому у наставника нет замечаний.
## Воспроизведение
1. Записать чистый, корректный опечатываемый план (без спорных мест).
2. Наставник возвращает `decision:GO` с `recommendation:""`.
3. Печать не встаёт; в логе `no_mentor_go`, судья не вызывался.
**Обход (подтверждён 16.06):** добавить в `## Переговоры` плана круг, прямо приглашающий
наставника записать forward-`recommendation` (напр. «при одобрении зафиксируй в
recommendation указание исполнителю …»). Тогда слот непуст → судья вызывается → печать встаёт.
Это костыль уровня контроллера, не лечит корень.
## Предлагаемый фикс (корень)
Сделать проверку-содержательности **decision-aware**:
- `decision === 'GO'` → пустой `recommendation` **допустим** (достаточно непустого `reasoning`
и/или `plan_points_addressed`); вердикт содержателен.
- `decision === 'NO-GO'` → требовать непустой `recommendation`/objection (как сейчас).
## Где искать в коде
Слой, считающий `no_mentor_go` и проверяющий содержательность вердикта наставника:
`mentor-verdict.mjs` / `judge-orchestrator.mjs` / `enforce-mentor-then-judge.mjs`. Искать
проверку пустых слотов вердикта (`пустые слоты`, `no_mentor_go`).
## Доказательство (лог AITUNNEL)
16.06.2026 14:17:32, эндпоинт `/v1/messages`, модель `deepseek-v4-pro`, ключ «Agent mentor»,
ответ ASSISTANT: `"decision": "GO"`, `"confidence": 0.95`, `"recommendation": ""`,
`plan_points_addressed` заполнен (обе претензии сняты) → оркестратор: `no_mentor_go`, судья не
вызван. На следующей итерации плана с Переговоры-кругом, приглашающим recommendation, наставник
вернул GO с непустым `recommendation` → судья вызвался → план опечатан.
## Связанная находка (для того же разбора)
Десинк **criterion-gate**: `enforce-supreme-gate` удаляет frozen-plan на совпадении
**последнего** шага плана раньше, чем `enforce-criterion-gate` (со-хук) проверит
`frozenPlanValid` → ложный блок git push «кодовое изменение без валидного запечатанного
плана». Лечится не-терминальным мутирующим шагом, но корень — порядок хуков (supreme-gate не
должен удалять печать, если со-хук в той же цепочке блокнёт действие). Тот же класс, что F-J.