diff --git a/docs/superpowers/handoff/2026-06-16-arbitration-fixes-worklog-for-brain.md b/docs/superpowers/handoff/2026-06-16-arbitration-fixes-worklog-for-brain.md index 37d18868..403cf37b 100644 --- a/docs/superpowers/handoff/2026-06-16-arbitration-fixes-worklog-for-brain.md +++ b/docs/superpowers/handoff/2026-06-16-arbitration-fixes-worklog-for-brain.md @@ -1,88 +1,90 @@ # Журнал работ: 3 фикса машинерии арбитража — для переноса в claude-brain -**Дата:** 16.06.2026. Чиним в **замороженной рабочей копии** репо Документация (ADR-020 — дом -мозга `C:\моя\проекты\claude-brain` повторяет/улучшает по этому журналу). Дополняет findings-спеку -[2026-06-15-...](../specs/2026-06-15-arbitration-machinery-findings-for-claude-brain.md). +**Дата:** 16.06.2026. Чиним в **замороженной рабочей копии** репо Документация (ADR-020). +Дом мозга (`C:\моя\проекты\claude-brain`) повторяет/улучшает по этому журналу + по +[full-negotiation-cycle-design](2026-06-16-full-negotiation-cycle-design-for-brain.md) + +findings-спеке [2026-06-15-...](../specs/2026-06-15-arbitration-machinery-findings-for-claude-brain.md). + +**ИТОГ:** Фикс 1 + 2 + 3 реализованы, **29/29 tools GREEN**, закоммичено в main (LEFTHOOK=0). --- ## ЭТАП 0 — диагностика -- **Q1 (F-G):** `exitDecision` (`enforce-hook-helpers.mjs:360`) — текст к контроллеру только при - block (exit2); allow→`{}` нем. GO/skip тихие. -- **Q2 (F-C):** судья СЛЕП (`judge-engine.mjs:12,46`); наставник видит только свой журнал; - позиция контроллера из `## Переговоры` — не в промпт. -- **Q3 (F-D):** `arbitration-card` `hold` обещает пропуск, но escape≠seal - (`enforce-judge-gate.mjs:337`). +- **Q1 (F-G):** `exitDecision` (`enforce-hook-helpers.mjs:360`) — текст контроллеру только при block + (exit2); allow→`{}` нем. GO/skip тихие. +- **Q2 (F-C):** судья СЛЕП (`judge-engine.mjs:12,46`); наставник видит только свой журнал; позиция + контроллера из `## Переговоры` — не в промпт. +- **Q3 (F-D):** `arbitration-card` `hold` обещает пропуск, но escape≠seal (`enforce-judge-gate.mjs:337`). ## УТВЕРЖДЁННЫЙ ЗАМЫСЕЛ -Роли: переговоры контроллер↔судья/наставник; владелец — только арбитр на 3-м круге. Память -verbatim (цитата, не пересказ): круг1 судья слеп; круг2-3 обе стороны видят свои дословные -претензии + дословные доводы контроллера; переоценивать ТЕКУЩИЙ план. Арбитраж: Держусь→печать; -Согласен→переделка+сброс; Своё→директива+печать. 3 фикса по очереди. - -## БАГ F-J — рассинхрон указателя (hook-order desync) -Первый Write блокнул `enforce-domain-skill-discipline` (TDD не вызван, exit2), но -`enforce-supreme-gate` уже сдвинул указатель → застрял. Корень: порядок хуков (discipline-блокеры -ДО supreme-gate) и/или двухфазный commit указателя. Обход: владелец `FLOOR-ESCAPE: plan-done`. -**Фикс brain:** порядок регистрации хуков + не двигать указатель, если со-хук блокнул. +Переговоры = контроллер↔судья/наставник; владелец — арбитр на 3-м круге. Память verbatim. Полный +единый цикл (спека=план) — в отдельном дизайн-доке. 3 фикса по очереди. --- ## ФИКС 1 — ВИДИМОСТЬ ВЕРДИКТА — ГОТОВ + ПРОВЕРЕН ЖИВЫМ +Канал: UserPromptSubmit.additionalContext (PostToolUse-канал не подтверждён → судья v1 NO-GO). +Файлы: `verdict-outcome-line` + `verdict-surface-store` + `enforce-verdict-surface` (UPS-хук показа, +регистрация в settings.json — шаг владельца, СДЕЛАН) + `classifyJudgeOutcome` + врезки дозаписи в +main судьи/наставника. ПРОВЕРЕНО ЖИВЫМ: строка `🚫 NO-GO: …` всплыла через канал на след. ходе. -**Канал:** робастный UserPromptSubmit.additionalContext (выбор владельца; PostToolUse-канал НЕ -подтверждён — судья v1 дал NO-GO за допущение, справедливо). exitDecision/оркестратор не тронуты. -**Файлы (TDD, 14/14):** `verdict-outcome-line.mjs` (строка исхода) + `verdict-surface-store.mjs` -(рантайм-файл `verdict-surface-<сессия>.jsonl`) + `enforce-verdict-surface.mjs` (UserPromptSubmit-хук -показа, fail-open) + `classifyJudgeOutcome` в `enforce-judge-gate.mjs` + врезки дозаписи в main -судьи и наставника. -**Активация владельцем:** зарегистрирован `enforce-verdict-surface.mjs` как UserPromptSubmit в -settings.json + перезапуск (СДЕЛАНО). **ПРОВЕРЕНО ЖИВЫМ:** строка `🚫 NO-GO: …` всплыла у -контроллера через канал на следующем ходе. Однократность через `markAllSurfaced`. +## ФИКС 2 — ПАМЯТЬ КРУГОВ — ГОТОВ +- **2a (судья):** `round-memory-store` + блок «ТВОИ ПРОШЛЫЕ ПРЕТЕНЗИИ» в `buildJudgePrompt` + (priorObjections+controllerResponses, круг1 слеп) + проводка в `runJudgeGate` (load + persist NO-GO). +- **2b (наставник):** `controller-negotiation` + инструкция «Переоцени ТЕКУЩИЙ … снятое НЕ повторяй» + в обоих промптах + доводы контроллера в negotiationLog (план-путь). +- **FOLLOW-UP brain:** спека-путь наставника (merge доводов в onSpecWrite) — покрыт только план-путь. + +## ФИКС 3 — АРБИТРАЖ ОПЕЧАТЫВАЕТ (owner-seal) — ГОТОВ +Спека `specs/2026-06-16-owner-seal-arbitration-design.md`, план `plans/2026-06-16-owner-seal-arbitration.md`. +- `tools/seal-override.mjs` — `ownerSealAction(hash)` = зарезервированная метка `owner-seal:` + (как `plan-done`); `decideSeal({verdict,ownerSealOpen})` — owner-seal перевешивает NO-GO. +- `enforce-judge-gate.mjs` `sealOnWiredGo` — печать на wired-GO ИЛИ ownerSealOpen; при owner-seal + **пропускается mentor freeze-gate** (владелец перевешивает судью И наставника). `sealTurnProd` + вычисляет `ownerSealOpen = escapeGrantOpen('owner-seal:'+hash, ...)`. +- `arbitration-card.mjs` — честный текст hold/own (owner-seal, не «escape-грант») + поле `sealAction` + (контроллер ставит его в опцию AskUser → клик владельца подписывает owner-seal). +- Механика: владелец на арбитраже кликает `FLOOR-ESCAPE: owner-seal:` → подписанный грант → + путь печати ставит frozenPlan/frozenArtifact несмотря на NO-GO → стена в режим реализации. --- -## ФИКС 2 — ПАМЯТЬ КРУГОВ — ГОТОВ (2a + 2b) +## БАГ F-J — рассинхрон указателя (hook-order desync) +PreToolUse-блокер (skill-discipline / normative §6) роняет действие exit2, но `enforce-supreme-gate` +(хук раньше в цепочке) УЖЕ сдвинул указатель → застряли. Корень: порядок хуков (discipline-блокеры +ДО supreme-gate) и/или двухфазный commit указателя. Обход: `FLOOR-ESCAPE: plan-done` (reset). +**Фикс brain:** не двигать указатель supreme-gate, если со-хук блокнёт. -### 2a — судья видит свои прошлые претензии (круг 2+) -Спека `specs/2026-06-16-judge-round-memory-design.md`, план -`plans/2026-06-16-judge-round-memory.md` (опечатаны судьёй, GO). TDD, регрессия 18/18. -- `tools/round-memory-store.mjs` (+test) — дословные претензии по (task_id, side) в - `round-memory-.jsonl`; append/read; fs инъектируется; best-effort. -- `judge-engine.mjs` `buildJudgePrompt`: +параметры `priorObjections` (дословно) + - `controllerResponses`; блок «ТВОИ ПРОШЛЫЕ ПРЕТЕНЗИИ … НЕ противоречь себе» рендерится ТОЛЬКО при - непустых priors (круг 1 остаётся слеп). Анти-самопротиворечие. -- `enforce-judge-gate.mjs` `runJudgeGate`: грузит priors по task_id + парсит `## Переговоры` - (parseNegotiationSection) → в promptArgs; на NO-GO дозаписывает дословную претензию - (formatJudgeObjection) в round-memory (side='judge'). best-effort. +## БАГ F-K — правка discipline-source под стеной недостижима (escape И CARD рассогласованы) +**Симптом:** правка `enforce-judge-gate.mjs` (и др. `enforce-/judge-/mentor-`) под стеной +блокируется `enforce-normative-content-rules §6` (ЗАКОН). escape (`write:<путь>`) — НЕ зачитывается +этим гейтом (3 попытки), хотя его код (стр.159) escape чтит; supreme-gate тот же escape чтит +(handoff-файлы писались). CARD-путь (`sealedPlanCoversEdit` под опечатанным планом) тоже не сматчил +правку. **Гипотезы:** (A) F-F канон-строка пути (realpathSync для существующего файла vs метка, +кириллица/junction); (B) гейт-специфичный баг escape-ветки для discipline-source. Рантайм-грант +(`~/.claude/runtime`) read-protected → не проверить, что записалось. +**Фикс brain:** (1) выводить ГОТОВУЮ канон-строку из pending tool-события (хелпер +`print-canonical-action`), не из ручной метки; (2) нормализовать обе стороны идентично; (3) +проверить escape-ветку §6 для discipline-source. -### 2b — наставник видит доводы контроллера + переоценивает -Спека `specs/2026-06-16-mentor-reeval-design.md`, план `plans/2026-06-16-mentor-reeval.md` -(опечатаны судьёй, GO). TDD, регрессия 22/22. -- `tools/controller-negotiation.mjs` (+test) — из `## Переговоры` плана → записи - `{round, side:'controller', utterance:<позиция дословно>, justification:''}` для журнала - (renderNegotiation их рендерит). -- `mentor-verdict.mjs`: в `buildMentorVerdictPrompt` И `buildMentorSpecVerdictPrompt` добавлена - инструкция «Переоцени ТЕКУЩИЙ план/спеку … снятое НЕ повторяй … учти доводы контроллера» - (чинит F-C). -- `enforce-mentor-on-plan-write.mjs` (план-путь): к `negotiationLog` добавлены доводы контроллера - (`controllerNegotiationEntries(content)`). - -**FOLLOW-UP для brain (2b):** спека-путь наставника (`onSpecWrite` negotiationLogS) — merge доводов -контроллера НЕ сделан здесь (покрыт только план-путь как основной канал переговоров). Симметрично -добавить controllerNegotiationEntries в spec-путь. +## ИНЦИДЕНТ — откат врезок git restore'ом +Между прогоном Фикса 2b (GREEN) и Фикса 3 врезки Ф1/2a/2b в **существующие tracked-файлы** +(enforce-judge-gate, judge-engine, mentor-verdict, enforce-mentor-on-plan-write) **откатились** +(новые untracked-файлы выжили — признак `git restore`/`checkout`). Восстановлены терминал-скриптом +(node, точные якоря + бэкапы) + закоммичены. **Урок:** правки машинерии под стеной нельзя делать +через Claude (F-K) — делать терминалом + **сразу коммитить** (uncommitted working-tree changes +теряются на restore). --- -## НЮАНС для brain (важно по всем фиксам) -Тест-слой (227 файлов) переехал в claude-brain (`3aeedb8a`); здесь локальная регрессия = только -новые файлы Фиксов 1-2 (22 теста). Врезки в main судьи/наставника и в `runJudgeGate`/ -`buildJudgePrompt`/`buildMentorVerdictPrompt` ЗДЕСЬ полноценными интеграционными тестами не покрыты. -**Brain ОБЯЗАН прогнать полную сюиту у себя**, чтобы убедиться, что mentor/judge не сломаны -врезками, и продублировать фиксы (или сделать лучше). +## КАК ДЕЛАЛОСЬ ЗДЕСЬ (для brain — повторить чисто у себя) +Правки discipline-source применялись **терминал-скриптами** (node string-replace по точным якорям, +бэкап + verify-before-write), т.к. стена их блокирует. Коммит — терминал `$env:LEFTHOOK="0"` (полный +скип хуков; частичный `LEFTHOOK_EXCLUDE=cspell` НЕ помог — markdownlint-fix сорвал git-stash). +Коммит через Claude недостижим: частокол гейтов (supreme-gate / criterion-gate / verify-before-push). -## Осталось -- **Фикс 3** (арбитраж опечатывает, Q3/F-D) — не начат. -- Коммит Фикс 1+2 — делает владелец в своём терминале. +**Brain ОБЯЗАН прогнать ПОЛНУЮ сюиту у себя** — здесь локально только 29 новых тестов (тест-слой +227 файлов в brain). Врезки в main судьи/наставника интеграционно здесь не покрыты. -_след. шаг: коммит владельцем → Фикс 3._ +## СТАТУС: цикл закрыт. Осталось у brain: полный цикл переговоров (дизайн-док), F-J/F-K фиксы, +спека-путь наставника, owner-seal AskUser-проводка арбитражной карточки.