Новый router-pin-store: пин совета роутера по (task_id, goalHash) пер-сессионно.
on-plan-write пин-aware: пин-попадание по неизменной цели → совет переиспользуется,
classifyImpl НЕ зовётся; промах/смена цели → classify + сохранение пина. Проводка в
активный наставник-хук инъекцией реального стора с sessionId (инъекция-выкл по умолчанию,
старое поведение/тесты целы). Хвост спеки роутера §4 (пининг по goalHash), эпик роутер-реестр
этап 3, item 2. Граница не тронута (recommended_chain, цепочки, observer-stop-hook, owner-seal).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
extractPlanGoal обрывал многострочную цель на первой строке (multiline $) и при
пустой строке под заголовком падал в фолбэк, хватавший skills-json-блок или Kind-маркер
как цель → роутер классифицировал план по мусору, пининг садился на мусор. Регекс теперь
берёт тело секции целиком до следующего заголовка / fenced-блока / конца текста; фолбэк
исключает заголовки и fenced-блоки; при нескольких секциях берётся первая.
Хвост спеки роутера §4 (вход роутера), эпик роутер-реестр этап 3, item 1.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
owner-seal был мёртв в тупике с наставником: наставник блокировал (exit 2) раньше,
чем оркестратор звал судью (а owner-seal читает только судья). Теперь
decideMentorObjection принимает ownerSealOpen; при открытом терминальном гранте
владельца наставник не блокирует (и на NO-GO, и на degraded) — пропускает к судье,
который печатает через ownerSealOpen. main() вычисляет owner-seal тем же
ownerSealOpenForEvent, что и судья. GO-путь не изменён.
Гайд стены: урок 2026-06-21 — при требовании наставника о церемонии вокруг
разрушительных шагов уступать и добавлять прогон проверки перед каждым; owner-seal
теперь работает и в тупике с наставником.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Снята зависимость парсера транскрипта наблюдателя от машинерии L-цепочек:
- observer-transcript-parser больше не импортирует observer-chain-detector,
не загружает observer-chain-map.json и не пишет primary_rationale.chain_ref;
- KNOWN_NODES больше не черпает имена из карты цепочек (источники: known-nodes.txt,
маркер direct, форменные правила #NN и плагин:навык);
- удалены observer-chain-detector.mjs(+test), observer-chain-map.json,
observer-retrofill-chain-ref.mjs(+test).
Граница не тронута: recommended_chain/recommended_node/chain_progress/chain_completed,
observer-stop-hook, командные цепочки, verifyChain. Полный свод зелёный.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
B2: router-classifier.mjs без buildChainsBlock и блоков «Available chains» (recommended_chain сохранён).
B3: удалены router-stop-gate(+test) и observer-chain-map-checker(+test); status-md-generator без
health-check C6; lefthook.yml без шага observer-chain-map-checker. observer-chain-detector и
observer-chain-map.json — снос отложен в под-этап (живые импортёры transcript-parser/retrofill/stop-hook).
Гайд: восстановлена markdown-разметка урока 2026-06-20. Полный свод зелёный.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Этап 3 эпика «роутер-реестр» (B1): из tools/node-graph.mjs убрана поддержка chains
(в buildNodeGraph) и функция hintLinksOf (живого импортёра нет); тест приведён в
соответствие (без hintLinksOf-блока и литералов chains). twinsOf/conflictsOf/resolveNode/
checkGraphFreshness сохранены. Полный свод зелёный (263 файла, 4414 тестов — прогон в чистом
терминале владельца; под Bash сессии воркеры коллапсируют от контеншна).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Этап 3 эпика «роутер-реестр» (фундамент): убран реестр именованных цепочек L1-L17
из schema.json (required/свойство chains/chain_membership/определение chain), nodes.yaml
(153 строки chain_membership + секция chains), registry-load.mjs (chains/findChainsByNode)
и его теста. recommended_chain и прочие границы D5 не тронуты. Полный свод зелёный
(263 файла, 4412 тестов). node-graph/router-classifier (Этап B) устойчивы к отсутствию chains.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
В конец гайда добавлен раздел «⚠️ Урок 2026-06-19»: NO-GO = свой дефект (читать objection,
не гадать); реальные дефекты (reformat structured / нет отката при RED); печать асинхронна
(не опрашивать runtime, ждать вердикт); не удалять seal-файлы; баннер ≠ вердикт текущего
плана; stop-loss; спека=ЧТО / план=КАК.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Этап 2c (a5d30f3) + 2d (внутри 2c) закрыты; Осталось = этап 3 (снос цепочек L) +
хвосты спеки 4/7 + инфра-долг (gitleaks/lychee bin). Граф жив как замена цепочкам.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
8 мест router-mentor-wall-GUIDE.md приведены к коду (reading-discipline.mjs:114 — ДР-1 снят;
criterion-gate.mjs:28 / verify-gate.mjs:38 — escape снимает гейты; supreme-gate actionOf:128 —
PowerShell-op не матчит; readonly-шаг не двигает указатель) + раздел автономности A-E
(нулевое вмешательство владельца на реализации, коммит по церемонии скриптом).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
После починки lefthook (commit 5fb9897) обычный git commit / git push gitea main
проходят без LEFTHOOK=0 при ОТСУТСТВУЮЩИХ инструментах (5 джоб обёрнуты
test -f <tool> || exit 0). LEFTHOOK_EXCLUDE остаётся только для pre-existing-находки
УСТАНОВЛЕННОГО инструмента. Заметка в раздел 5 (коммит/пуш) router-mentor-wall-GUIDE.md.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Ремонт инфра-долга (после сплита ADR-020 не установлены gitleaks/markdownlint/
cspell/lychee → pre-commit жёстко падал, форсил глухой LEFTHOOK=0):
5 джоб pre-commit/pre-push обёрнуты в `if test -f <tool>; then <run>; else echo skip; fi`.
- инструмент отсутствует → джоба ПРОПУСКАЕТСЯ (коммит не срывается);
- инструмент есть и нашёл проблему → по-прежнему БЛОКИРУЕТ (if/then/else, не ||);
- рабочие контролёры (adr-judge/cross-ref/observer/registry) идут на каждом коммите.
Учёт этапа 2b: splitting-inventory +секция статуса (2a/2b DONE, осталось 2c/2d/этап3);
план этапа 2 (vocabulary-graph) + спека/план церемонии фиксации внесены в репозиторий.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
ui-ux-pro-max row + решение C: нормативный квинтет-sync вокруг NB-заметки
PSR (9e17fad) выполнен — PSR v3.26 / Tooling v2.27 / CLAUDE.md v2.48 /
CHANGELOG; Pravila без изменений (forward-compat). Коммит sync f1cdd7e.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Формальный квинтет-sync вокруг NB-заметки PSR (commit 9e17fad):
ui-ux-pro-max развёрнут в реестре навыков на 7 гранулярных карточек
ui-ux-pro-max:<навык>; роль не изменена (материал/не решатель; R6.0
Vue+Vuetify; финальный код Frontend Design #30; R10.1/R11.5/R14.3/R14.5).
Содержательных изменений R0-R16: 0.
- PSR v3.25 -> v3.26 (шапка + История версий)
- Tooling Прил.Н v2.26 -> v2.27 (cross-ref PSR v3.25->v3.26; счётчики без изменений)
- CLAUDE.md v2.47 -> v2.48 (§0 cross-refs + §9) + CHANGELOG зеркало
- Pravila v1.45 без изменений (живые cross-refs на PSR forward-compat «+»)
Через normative-sync агента (§15 governance) + ручная верификация/правка
контроллером. Счётчики инструментов не изменились.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
§5 п.14: прежний текст утверждал «6305 узлов / покрывает app/» (полный
до-сплитовый граф, живший в junction spike-worktree). После ADR-020 (app/
вырезан) graphify-out/graph.json = частичный срез ~39 узлов, только docs/,
без app/; graphify-out/ теперь обычная папка, не junction. Старые цифры
сохранены как историческая пометка «было до сплита»; для полного актуального
графа — /graphify --update.
Правка-факт внутри CLAUDE.md (через claude-md-management); Pravila/Tooling
её не дублируют → синхрон квинтета не требуется, версия §9 не бампалась.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Эпик роутер-реестр. После разворачивания комка ui-ux-pro-max в 7 карточек
(commit предыдущий) — заметка в PSR §«плагины вне stack'а»: UPM теперь
адресуется как ui-ux-pro-max:<навык>, НО роль не изменилась (материал, не
решатель; стек Vue+Vuetify R6.0; код — Frontend Design; R10.1/R11.5/R14.3/R14.5
применяются к 7 карточкам как раньше к одной).
Минимальная документарная правка под авторизацию владельца «делай нормативку».
ОТЛОЖЕНО (во избежание §15 коллизии с параллельной сессией в Pravila):
формальный sync квинтета — версия PSR + cross-refs в CLAUDE.md/Pravila/Tooling.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Внесён единый раздел §18 «Дисциплины работы агента под управляющим слоем»: 18.1 A (препятствие
на ходу — перепланируй, не гадай), 18.2 D1 (деплой — читать вывод каждого шага, стоп на аномалии,
опасное — per-command согласие), 18.3 D2 (сохранение под ревью — раздельные согласия деплоя/коммита,
опасное вне общего согласия). Нормативная формулировка действующего поведения; код не меняется.
Версия свода v1.44 -> v1.45; история догнана записью v1.44 (Perplexity Pack). Через церемонию стены:
спека (v3) + план (v4-push) опечатаны наставником+судьёй; §6-правка авторизована escape владельца.
Синхрон квинтета (PSR/Tooling/CLAUDE.md) — отдельным шагом.
GUIDE (bags/router-mentor-wall-GUIDE.md): +урок про escape-окошко (строку давать в чат для
копирования, вставлять в поле ответа окошка) +урок про коммит/пуш шагами плана (обоснование
docs-only git под claude-md-management).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Anti-cosmetic-детектор (>2 простых AskUser за сессию → hard-block, требует brainstorming) глушил
ЛЕГИТИМНЫЙ поток escape-окошек: владелец даёт разрешение FLOOR-ESCAPE через AskUser, и после >2
таких окошек стена их блокировала — нормативку под стеной нельзя было довести (баг найден живым
прогоном 18.06). Фикс по аналогии с git-approval exemption (Calibration 5): isEscapeAuthQuestion
(вопрос несёт метку FLOOR-ESCAPE) освобождается в decide() — не косметика, не считаем, не блокируем.
Не абьюзится: метка сигналит авторизацию владельца, а не подмену идеации. Свод 4383 зелёный.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Судья мог судить/печатать план, который наставник завернул: mentor-GO привязан к plan_hash =
planId(steps) (только шаги), пишется ТОЛЬКО на GO и НЕ стирался на NO-GO. При идентичных steps
(менялся лишь текст плана) старое «да» переживало смену содержания — судья находил устаревшее
одобрение (mentor-go-store::mentorGoValidFor по plan_hash) и проходил mentorApproved-гейт несмотря
на свежий NO-GO наставника. Вскрыто живым прогоном (план опечатался при mentor NO-GO + judge GO).
Фикс: clearMentorGo стирает запись; enforce-mentor-on-plan-write на реальном NO-GO (blocked) её
зовёт (degraded не трогаем — verdict неизвестен). Инвариант: «да» наставника живёт ⟺ последний
проход одобрил. Свод 4376 зелёный.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Контроллер видел голое «NO-GO [judge]» без претензий: показ вердикта берёт поле reason, а
pushVerdict писал reason = verdict.reason || recommendation — у судьи recommendation пуст (суть в
objections[]), и возражения терялись. Хотя они есть в системе (карточка арбитража / память кругов
через formatJudgeObjection) — просто не в показ. Новая judgeSurfaceReason(verdict): reason/
recommendation, иначе formatJudgeObjection(verdict.verdict) — дословные возражения. runJudgeTurn
использует её для pushVerdict + writeStage. Поймано вживую: судья дал delivery=internal[heavy] +
позиция-без-якорей[light], а контроллеру пришло пусто. Свод 4374 зелёный.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Раздел «Аварийный выход» переписан под Поза 1 (consent-forgery A+B1-B5+C): старый рецепт
«контроллер кладёт FLOOR-ESCAPE в КНОПКУ» снят (anti-button отвергает) → ЛЁГКОЕ согласие
владелец набирает САМ свободным вводом (контроллер не диктует — anti-dictation), ТЯЖЁЛОЕ
(owner-seal/ops-runbook/commit/plan-done/gate3-arb/разрушит. bash) — ТОЛЬКО из терминала
владельца (node tools/owner-consent.mjs <sessionId> <action>, подпись fail-closed). Добавлена
заметка в «Обновления 18.06» с коммитами эпика. Оперативная шпаргалка (не нормативный квинтет).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Свободный floor_escape (лёгкий escape в чате) НЕ доверяется, если контроллер в своём тексте
текущего хода инструктировал владельца вписать метку. processEvent читает текст контроллера
из транскрипта хода (readTranscript + lastAssistantText, переиспользован), один раз на событие
зовёт detectOtherSocialEng (раньше был мёртвой проводкой — не вызывался нигде); flagged →
floor_escape не пишется. Паттерны detectOtherSocialEng усилены императивной диктовкой метки
FLOOR-ESCAPE (глагол рядом; простое упоминание концепта не флагуется). fail-open observability —
сбой чтения транскрипта → как раньше. Применяется к floor_escape (git-approval закрыт #A).
Завершает кодовую часть эпика (A + B1-B5 + C). Спека §C. Свод 4350 зелёный.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Per-command escape несущего пола (rm -rf / git push --force / migrate:fresh / db:wipe / запись в
runtime/секрет) открывается ТОЛЬКО терминальным грантом владельца (origin+подпись, fail-closed),
не chat floor_escape — Поза 1. Пол по определению блокирует лишь необратимое → весь его escape
тяжёлый: enforce-floor::main грузит loadTerminalGrants вместо loadFloorEscapes. decide()/floorDecide
агностичны источнику — логика и тесты пола не тронуты. Стена (supreme-gate 396) не правится: пол
(matcher '*') связывает первым. Завершает Часть B (терминал-канал). Свод 4346 зелёный, пол 12/12.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Снятие печати плана (plan-done) и арбитраж gate3 (gate3-arb:accept/continue) — тело-агностичные
согласия, обходящие/снимающие стену — теперь открываются ТОЛЬКО терминальным грантом владельца
(Поза 1, HOLE-4). supreme-gate: новый параметр terminalGrants в decideMode/runGate, PLAN_FINISH_ACTION
проверяется против него (лёгкий escape остаётся на chat-грантах); main грузит loadTerminalGrants.
gate3-loop: арбитраж-гранты грузятся через loadTerminalGrants (loader-swap; resolveOwnerArbitration
агностична). Ядро стены: 138/138, gate3 44/44, полный свод 4346. Спека §B/§DEC.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
ops-runbook:<hash> (деплой) и commit:<hash> (коммит агентом) открываются ТОЛЬКО
терминальным грантом владельца (origin:owner-terminal + валидная подпись, ключ обязателен —
fail-closed #KEY), не chat floor_escape — Поза 1. loadPlanScopedGrants переписан как
loadTerminalGrants + фильтр по префиксу (origin/подпись/нижняя граница в одном месте, DRY).
Мосты blessed-ops/commit-grant не тронуты (читают через те же обёртки). Тесты загрузчиков
переписаны под новый контракт. Спека §B/§KEY/§CRIT6.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Печать «одобрено владельцем» (owner-seal) теперь открывается ТОЛЬКО терминальным грантом
владельца (loadTerminalGrants), не chat floor_escape — Поза 1 для самого тяжёлого согласия.
Вычисление вынесено в тестируемую ownerSealOpenForEvent (источник грантов инъектируется);
sealTurnProd зовёт её с loadTerminalGrants. sealOnWiredGo (берёт ownerSealOpen параметром) и
его тесты не тронуты. Убран ставший неиспользуемым верхний импорт loadFloorEscapes
(escape-валве судьи берёт его динамически). Спека §B/§CRIT7.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Несомненный канал согласия для тяжёлого (Поза 1): floor_escape с origin:owner-terminal,
подписанный ключом keychain. Скрипт владельца tools/owner-consent.mjs строит+подписывает+
пишет грант (запускает владелец; контроллер не может — нет ключа + floor режет запись runtime).
Читатель loadTerminalGrants принимает ТОЛЬКО origin-помеченные валидно-подписанные гранты,
ключ обязателен (fail-closed, #KEY). Нулевой радиус: живые потребители НЕ тронуты —
подключение (owner-seal/ops-runbook/commit/plan-done/gate3/bash) отдельными заходами B2+.
Спека: specs/2026-06-18-consent-forgery-fix-design.md §B/§KEY.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>