# BUG: owner-seal не перебивает mentor NO-GO (мёртвая проводка)

**Дата:** 2026-06-16. **Репозиторий хука:** claude-brain (+ замороженная копия в портале).
**Severity:** high — арбитражная развязка owner-seal нефункциональна именно в том случае, для которого создана.
**Подтверждено вживую** в сессии 2026-06-16 (церемония коммита 2 docs-файлов).

## Симптом
Наставник даёт NO-GO (неустранимая претензия). Владелец выдаёт подписанный пропуск
`FLOOR-ESCAPE: owner-seal:<planHash>` (среда его пишет и подписывает). Печать ВСЁ РАВНО не встаёт —
план остаётся неопечатанным, стена в разговорном режиме. Пропуск фактически игнорируется.

## Корневая причина (по коду)
1. `enforce-judge-gate.mjs:115-117` — `runJudgeGate`: при отсутствии mentor-GO возвращает
   `{decision:"GO", wired:false, skip:"no_mentor_go"}` (wired:FALSE).
2. `enforce-judge-gate.mjs:308` — `runJudgeTurn`: вызывает печать `deps.onWiredSeal` (= `sealTurnProd`,
   ЕДИНСТВЕННОЕ место, где читается owner-seal) ТОЛЬКО внутри `if (verdict && verdict.wired)`.
3. Итог: mentor NO-GO -> wired:false -> ветка печати пропускается целиком -> `sealTurnProd` не
   вызывается -> `ownerSealOpen` (escapeGrantOpen для owner-seal) НИКОГДА не проверяется.
   owner-seal спрятан за тем самым GO, который должен перебивать. Мёртвый код.
4. Доп. барьер: даже если бы `onWiredSeal` вызвался с NO-GO-вердиктом, `sealPlan`
   (`seal-orchestration.mjs:37-38`) и `sealArtifact` (`:27`) делают `if (!isRealGo(verdict)) return {sealed:false}` —
   второй гейт, тоже режущий owner-seal. `seal-override.mjs::decideSeal` (чтит ownerSealOpen) в этот
   путь НЕ подключён — реально используется `sealOnWiredGo`->`sealPlan`.

## Направление фикса
- Проверять `ownerSealOpen` ДО гейта `verdict.wired` (или звать `onWiredSeal`, когда есть валидный
  owner-seal-грант на planHash), И ослабить `isRealGo`-гейт в `sealPlan`/`sealArtifact` при ownerSealOpen.
- Свести проводку к `seal-override.mjs::decideSeal` (он уже корректен).

## Сопутствующие баги, найденные тем же расследованием
- **Карточка арбитража не показывает hash.** `enforce-mentor-on-plan-write.mjs:44-48` строит карточку
  без `sealAction`, хотя `arbitration-card.mjs` его принимает. Владельцу негде взять `owner-seal:<hash>` —
  приходится лезть в runtime `mentor-verdict-<sess>.json` поле `planHash`. Фикс: передавать
  `sealAction: ownerSealAction(planId(steps))` и печатать его в `buildMentorArbitrationMessage`.
- **Счётчик кругов не сбрасывается сменой файла.** `planId = sha256(canonicalJson(steps))`
  (`plan-lock.mjs:15`) зависит ТОЛЬКО от шагов -> одинаковые шаги = один plan_id -> round-memory копит
  круги (наблюдали 4->11) даже при новом имени плана. К «3-му кругу» (окно owner-seal) вернуться нельзя
  без ветки «accept/сброс», которая требует устранимой претензии.
- **Резолвер вставляет неустранимую строку.** В контекст, показываемый наставнику, добавляется заголовок
  «--- ПРОВЕРЕННЫЙ КОНТЕКСТ (резолв цитат, НЕ истина — ревью владельца обязателен) ---». Этой строки нет
  в файле -> контроллер не может её удалить -> наставник в цикле требует удалить -> вечный NO-GO на любом
  плане с verified-context. Сцепка с багом owner-seal делает тупик невыходимым изнутри стены.

## Репро (2026-06-16)
Церемония коммита 2 файлов диагностики Gitea. planHash плана коммита:
`6fd7b1dceb004d3667e03466d67ce3df79ef9e85638302b2a0ad6b2589461edd`.
Владелец кликнул `FLOOR-ESCAPE: owner-seal:6fd7b1...` -> грант подписан -> план остался неопечатанным
(supreme-gate: «разговорный режим»). Цепочка no_mentor_go -> wired:false -> onWiredSeal пропущен.
