Ещё два пользовательских пункта (по запросу владельца): (A) maintenance — точные шаги выключить/включить стену через settings.json hooks; (D) если lefthook ругается на STATUS.md — git restore --staged --worktree перед commit. Согласовано.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Два пользовательских пункта по итогам сессии 14.06: (B) перезапуск Claude Code перечитывает settings.json, но не сбрасывает застрявшую печать/сессию — сброс через досрочное завершение или новую церемонию с другим именем; (C) запись в память/правила про саму стену by-design требует escape владельца или maintenance. Согласовано владельцем (в+с).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Новый enforce-mentor-then-judge.mjs запускает наставника дочерним процессом до конца, потом судью (свежий mentor-GO/вердикт) - убирает гонку параллельных PostToolUse-хуков. Машины enforce-mentor-on-plan-write/enforce-judge-gate байт-в-байт не тронуты. Зарегистрирован в settings.json. TDD +5 тестов.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
loadFloorEscapes (единственный ВЫДАЮЩИЙ читатель floor_escape) теперь key-gated
проверяет подпись: ключ есть → оставить только валидно-подписанные (форж/
неподписанный/битый отброшены); нет ключа (truthy) → принять все (как сегодня,
content-floor backstop).
- Рефактор: generic loadRecords → floor_escape-специфичный readFloorEscapeRecordsAt,
возвращает ПОЛНЫЕ записи {type,action,ts,sig} (не stripped) для верификации.
Единственный вызыватель — loadFloorEscapes (loadConsumed читает другой файл).
- loadFloorEscapes(sessionId, now, {keyImpl, fsImpl, runtimeDir}) — 3-й опц.
аргумент, обратно-совместим (8 потребителей зовут loadFloorEscapes(sess)).
- ОТКЛОНЕНИЕ от дословного кода плана (одобрено владельцем): быстрый путь —
пропусков нет → [] БЕЗ резолва ключа. Поведение §3/§6 идентично, но keychain-
subprocess не дёргается на каждый tool-use в массовом пустом случае
(loadFloorEscapes — gate hot-path; 5 из 8 потребителей keychain не читали).
TDD: 6 новых тестов — 4 key-gated (signed принят / forged+tampered отброшены /
ключ null → все / '' falsy → все / окно 5 мин), 2 на быстрый путь (нет записей /
нет файла → [] без вызова ключа). Регрессия существующего escape-grant GREEN
(26 тестов). Суммарно 32 GREEN по затронутым файлам.
План: docs/superpowers/plans/2026-06-10-floor-escape-signing.md (Task 3)
Прод-код инертен до провижининга ключа (Фаза 8). Гейт закрытия — следующим шагом.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
processEvent (PostToolUse AskUser) теперь подписывает floor_escape-пропуск
подписью FLOOR_ESCAPE, когда ключ доступен (resolveReceiptKey):
- +keyImpl=resolveReceiptKey, fsImpl={appendFileSync,mkdirSync} — инъекция для
hermetic-тестов; резолв ключа один раз на событие (fail-safe: ошибка → key=null
→ floor_escape пишется неподписанным, PostToolUse-наблюдаемость не ломается).
- esc подписывается только при наличии ключа; approve_git_operation (rec) НЕ
трогаем (§2.2). Нет ключа → esc без sig (как сегодня).
- Запись через fsImpl.* вместо прямых node:fs.
TDD: 2 новых теста (ключ → валидная подпись; ключ null → без sig). Регрессия
существующего enforce-askuser-answer-parser GREEN (approve_git_operation-путь цел).
Суммарно 10 GREEN по затронутым файлам.
План: docs/superpowers/plans/2026-06-10-floor-escape-signing.md (Task 2)
Прод-код инертен до провижининга ключа (Фаза 8).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
assertValidJudgeMode guard in freezePlan/freezeArtifact: fail-CLOSE on any
mode != {null|shadow|live-block}. Closes YAGNI-candidate from sealed-plan §11
/ gate1+se2 §4 (SE-a) — bogus mode can no longer enter a seal at the source
(complements the wall's fail-closed live-block whitelist).
- freezePlan validates the judgeMode param; freezeArtifact validates the
embedded artifact.judge_mode (injected by seal-orchestration).
- guard sits before id/sig computation -> no partially-signed bogus-mode seal.
- throw is best-effort-swallowed at enforce-judge-gate.mjs onWiredSeal ->
no seal produced (fail-CLOSE), hook never crashes.
- real flow never trips it (judgeGateMode yields only inert/shadow/live-block,
inert never seals) — drift-only guard.
TDD: new tools/plan-lock-judge-mode.test.mjs (6 tests). Regression tools-only
3449 passed / 2 skipped / 0 failed (was 3443+2skip). 0 regressions.
sharp-edges + variant-analysis: clean (only two seal producers, both guarded;
wall comparison already fail-closed).
Plan: docs/superpowers/plans/2026-06-09-seal-time-judge-mode-validation.md
Производство двух печатей (артефакт-решение + план-шаги), чтобы стене М2 было
что матчить — код-предусловие флипа. Inline TDD, спека/план одобрены владельцем.
- C1 artifact-from-spec.mjs: спека markdown -> {sections, source_sha} по якорям {#id} (P2-2).
- C2 plan-steps-parse.mjs: план -> [{op,object,ref}], fail-CLOSE, reject op:Task (VA-4),
канон object = repo-relative POSIX (SE-5; pathNormalize только на матче в стене, не на парсе).
- C3/C4 plan-lock.mjs: judge_mode в ПОДПИСАННОЙ базе freezePlan (VA-2) + атомарный persist
temp->rename для обоих save (SE-4/VA-3, артефакт ДО плана).
- C6 seal-orchestration.mjs: sealableArtifact/sealablePlan + judgedHashOf (SD-1) +
sealArtifact/sealPlan на РЕАЛЬНОМ GO (SE-3 wired===true), штамп artifact_id из текущего
артефакта (SD-3), judge_mode впрыснут в печать ПОСЛЕ хеш-сверки sealOnApproval (фикс TOCTOU).
- C5 enforce-judge-gate.mjs: SPEC_PATH_RE + sealOnWiredGo (печать на wired GO, инъекция в main,
юнит-тесты hermetic) + judged_hash в вердикте runJudgeGate. extractGate2Product не тронут
(Гейт-2 = планы; Гейт-1 spec-judging — отдельный заход перед флипом).
- Интеграция seal-to-wall: печать -> decideMode стены М2 (allow / non-match block / closed-door).
Тесты: full tools-only регрессия 3427 passed | 2 skipped, 0 регрессий (+29 новых кейсов).
Печать в рантайме НЕ производится до флипа (стена/судья не зарегистрированы) — сборка
готовит код-предусловие. Спека docs/superpowers/specs/2026-06-09-sealed-plan-production-design.md.
findOverride/findOverrideAttempt/loadOverrideVocab become permanent stubs returning null/null/empty.
Non-deleted hooks (verify-before-push, tdd-gate, memory-coverage, branch-switch) still import these
symbols and need them to compile; runtime always reports 'no override'.
Adapted 15 existing tests in enforce-hook-helpers.test.mjs and 7 in enforce-semgrep-security.test.mjs
that asserted old vocab behaviour; all now assert stub behaviour (null/empty).
1824/1824 vitest tools GREEN.
Stream G of router-gate v4 deployment.
Two operational gotchas discovered в session 29.05.2026 (router-gate v3.6-3.8 sweep + post-sweep memory updates):
1. §5 п.13 NB — docs-only short-circuit считает строго .md-суффикс.
cspell-words.txt / package.json / lefthook.yml рядом со spec.md
делают diff mixed → verify-before-push активен → нужен vitest sentinel
ИЛИ override. Прецедент: commit 46c43169.
2. §5 +п.15 — enforce-memory-coverage hook не принимает chain-каналы
(chain:commit-push-mem-sync etc); требует строго direct:memory-sync
в свежем turn'е. Memory updates как часть multi-step задачи планировать
отдельным turn'ом или использовать memory dump override.
Прецедент: 4-й шаг sweep задачи заблокирован.
Via /claude-md-management:revise-claude-md skill flow.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Markdownlint added blank line before list in TL;DR v3.5 Changes section. Cosmetic, no semantic change. Captured to keep working tree clean for session handoff.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Dedicated brainstorm на S8 (последний acceptable residual после v3.4) — controller-writable markers BRANCH-SWITCH-CONFIRMED / RECOVERY-INTENT: заменены на AskUserQuestion-gate через расширение §4.5 answer parser. Тот же class fix что S5 v3.4 — перенос сигнала в side-channel который controller не контролирует.
V3.5 architectural shift:
- Old: controller wants git rebase → hook видит блокировку → controller пишет BRANCH-SWITCH-CONFIRMED в response → hook читает, allows. Самоодобрение через controller-written text.
- New: controller wants git rebase → hook блокирует → controller обязан AskUserQuestion('Выполнить git rebase main?') с 3 опциями → user picks → §4.5 parser распознаёт git-pattern, пишет approve_git_operation запись в askuser-decisions.jsonl с approved_action_pattern exact → controller retries → hook читает askuser-decisions, exact-match approval, consumes one-shot, allows.
Anti-forgery 4 защиты:
- askuser-decisions.jsonl в protected paths (~/.claude/runtime/*)
- Пишется только §4.5 parser при реальном AskUser-ответе
- Strict exact-match approved_action_pattern против tool_input.command
- 5-min time window + one-shot consumption (consumed flag)
Adversarial pre-check v4.3 — 6 attack-векторов проверены, все заблокированы.
5 spec edits:
- §3 preserved hooks таблица — enforce-branch-switch row переписан (no longer reads response markers, instead reads askuser-decisions)
- §4.5 — новый row + новое enum gate_interpretation: approve_git_operation
- §9 — S8 убран из acceptable residual list. Список residual теперь ПУСТ.
- §10.2 — askuser-decisions schema +consumed/consumed_at/consumed_by_tool_use_id + полный schema приведён
- §11 v3.5 history entry
Implementation budget: 21.5-31h (v3.4) → 22.5-32h (v3.5). +1.1h за: rewrite hook, extend parser, one-shot consumption, schema, spec edits.
Главный урок: класс controller-writable signals закрыт архитектурно через обе v3.4 (file side-channel) и v3.5 (askuser-decisions side-channel). Формула generalisable — любой controller-writable signal закрывается переносом write-канала в protected file который пишет отдельный gate-процесс при harness-driven событии.
Hard wall теперь полный hard. Acceptable residual list пуст.
Verify-sentinel: 1179/1179 vitest tools-only GREEN.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Handoff document for transition to new session. Contains:
- TL;DR of where we left off (spec v3.1 ready, impl not started)
- 4-step instructions for next session (read spec, writing-plans,
subagent-driven impl, post-impl tasks)
- Context (brain-retro #10 trigger, self-retrospect #2 confirmation,
user choice of Level 4)
- 7 design principles from spec section 2
- Architecture TL;DR (gate, 4 behaviors, baseline, deletes, preserved)
- All 4 spec versions in git with commits
- Cross-refs to L1+L2 plan, brain-retro, self-retrospect
- 5 open questions for writing-plans phase
Cannot write to memory/ path in this turn (memory-coverage hook
requires direct:memory-sync coverage, current turn has different
coverage). Memory entry can be added in next session via Skill or
manual annotation.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Comprehensive analysis of v3 found ~24 minor issues (no critical bypasses).
V3.1 closes most via clarifications to prepare for writing-plans skill in
next session.
Additions:
- TL;DR at top — fast orientation for implementer
- 10.1 Function and registry references (nodeMatches source,
registry source docs/registry/nodes.yaml, SDD-skill impact,
coverage-hint to recovery resolution)
- 10.2 State file schemas (8 files: router-state, chain-state,
askuser-decisions, router-gate-decisions, subagent-inheritance,
coverage-hint, gate-errors, gate-config)
- 10.3 Test strategy: ~150 unit + 10-15 integration + 10-15 golden
snapshot + 5-7 smoke
- 10.4 Success metrics: quantitative (override drops to 0,
gate-decisions growing) + qualitative (lockout < 5/100,
correct% > 60%) + acceptance criteria
- 10.5 Rollback plan (3 levels: hook off / revert commits / v2 baseline)
- 10.6 Stages and parallelism: 6-9h wall-clock with SDD parallelism
vs 13.5-20h sequential
No architectural changes — v3.1 only clarifies what implementer needs
to know without making implicit decisions.
Spec versions in git:
- v1: 7a43c175
- v2: b510a758
- v3: b632bcba
- v3.1: this commit
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>