Commit Graph

2008 Commits

Author SHA1 Message Date
Дмитрий dc30c5daee feat(m7-phase0): disciplineOutcome fail-CLOSE + P-7 списки + контракт helpers:7 (правило 1) 2026-06-08 10:02:43 +03:00
Дмитрий bbd66c9b61 feat(m7-phase0): canonicalAction тотальна — внешний try + pathNormalizeSafe (правило 7а) 2026-06-08 09:59:29 +03:00
Дмитрий 06ad12cd94 feat(m7-phase0): pathNormalizeSafe — тотальный normalize (правило 7а) 2026-06-08 09:57:41 +03:00
Дмитрий 8153f96aff docs(m7): build-handoff #3 — Фаза 1 content-floor собрана + PS single-source (HEAD 8e56df38)
Сменяет build-handoff #2. Фиксирует: Фаза 1 (content-floor V1/V1-PS) реализована
полностью (11 коммитов 1c251d25..8e56df38), регрессия 3044+2 GREEN 0 регрессий,
commit-not-push. Готовый промт новой сессии + цепочка скилов (executing-plans драйвер,
per-Task audit→TDD→systematic-debugging→verification, строгий sharp-edges после опасных
Task, гейт закрытия audit→sharp-edges→variant-analysis→regression→verification) +
квирки (vitest фильтры раздельно, гейты блокируют rm/git rm, tdd-real-test-verifier diff
требует expect, for-of не it.each) + отложенное в Фазу 8 (удаление powershell-destructive,
полная PS enumeration). Следующий шаг — Фаза 0 через writing-plans по команде владельца.
2026-06-08 09:40:25 +03:00
Дмитрий 8e56df3842 refactor(m7-floor): PS-content единый источник — matchPsHardBlacklist в shell-content-rules (variant-analysis)
Закрывающий variant-analysis-гейт Фазы 1 вскрыл класс P-1 для PowerShell: у
powershell-gate был СВОЙ PS_HARD_BLACKLIST (29 паттернов), а пол использовал
отдельный узкий psContentBlock (7) — подмножество, которое дрейфовало бы (та же
проблема, что P-1 для Bash). После Фазы 8 (увольнение powershell-gate) пол оказался
бы слабее гейта, который он заменяет. Решение владельца: исправить сейчас.

Зеркало P-1:
- PS_HARD_BLACKLIST + matchPsHardBlacklist перенесены в единый дом shell-content-rules;
  powershell-gate ре-экспортирует (тест single-source-identity: ссылка gate === SCR).
- +bare-egress (Invoke-WebRequest/iwr/irm/curl/wget bare — floor НЕ default-deny, нужен
  в blacklist, не только в whitelist гейта) +rmdir +rm (алиасы Remove-Item, которые гейт
  ловил whitelist'ом default-deny — полу нужны явно).
- psContentBlock стал ТОНКИМ делегатом над matchPsHardBlacklist (симметрия с
  bashIsContentBlock); пол через него видит ТОТ ЖЕ набор, что гейт. Дрейф невозможен.
- Следствие (осознанно): floor теперь блокирует все Set-Content/sc/$env/Az/… как гейт
  (симметрия с Bash-полом, блокирующим все cp/mv/redirect). Escapable. FP-толерантность
  унаследована от гейта (например `sc query`/`del.txt` — gate-aligned, fail-safe).

powershell-destructive.mjs физически не удалён (живые gate'ы блокируют rm/git rm) —
оставлен тонким делегатом (НЕ второй источник). Удаление — follow-up по git-approval.

Регрессия tools-only: 3044 passed + 2 skip (baseline 2843+2, 0 регрессий).
2026-06-08 09:34:23 +03:00
Дмитрий 473fd21136 feat(m7-floor): §12 content-floor инвариант — весь BASH_HARD_BLACKLIST floored (P-6)
Task 1.6 Фазы 1 М7. Тест-генератор: КАЖДАЯ запись BASH_HARD_BLACKLIST рубится полом
даже как валидный шаг плана. Итерация по экспортированному списку → полнота порта ПО
КОНСТРУКЦИИ: новый паттерн без сэмпла → красный (drift-детектор), floor не рубит →
красный. Анти-регресс «непробиваемости» закреплён за Фазой 1 (P-6), не за §9.2-smokes.
+C16 stderr-redirect + #34 injection (отдельные ветки matchBashHardBlacklist).

Полная регрессия tools-only: 2997 passed + 2 skip (baseline 2843+2, +154 Фазы 1,
0 регрессий). 99 floor-decide GREEN.
2026-06-08 09:16:04 +03:00
Дмитрий 6556f5ca0a test(m7-floor): инвариант escape снимает content-block (Bash+PS) + специфичность P-2
Task 1.5 Фазы 1 М7. Код уже escapable (1.3/1.4) — тесты фиксируют инвариант против
регресса. Покрыто: Bash node -e + PS Remove-Item + PS forge-write снимаются точным
грантом; P-2 специфичность (грант A не открывает команду B) для PS И Bash; кросс-shell
изоляция (Bash-грант не открывает PS-команду — разные canonicalAction-префиксы). 72 GREEN.
2026-06-08 09:13:55 +03:00
Дмитрий 183733835f harden(m7-floor): PS-алиасы forge+delete (sharp-edges после 1.4)
Строгий sharp-edges-гейт после Task 1.4 вскрыл обход через PowerShell-алиасы:
- forge P-3: `sc`/`cpi`/`ni` (алиасы Set-Content/Copy-Item/New-Item) писали в
  ~/.claude/runtime/.env мимо литеральных глаголов → подделка escape-гранта.
  Закрытие: PS_WRITE_VERB_RE += sc/ac/cpi/copy/mi/move/ni/tee (path-gated, FP только
  с протектед-путём; контроль `sc query` не over-блокируется).
- delete: `del`/`ri`/`rd`/`rmdir`/`erase` -Recurse -Force обходили литеральный
  Remove-Item. Закрытие: PS_CONTENT_BLOCK_RE алиасы для long+short флагов.

154 GREEN (floor + powershell-destructive + enforce-floor + supreme-gate).
Отложено в Фазу 8 §5 (карты покрытия): `&` call-operator, Invoke-Command (icm),
PS sub-expression $(), полная enumeration алиасов — coverage, не структурный класс.
2026-06-08 09:12:38 +03:00
Дмитрий ea83a714e4 feat(m7-floor): floor-decide ветка PowerShell content-block + forge-страж (V1-PS, P-3)
Task 1.4 Фазы 1 М7. Ветка PowerShell пола (после Bash, до OBSERVE_TOOLS): psContentBlock
(Remove-Item/-Recurse/iwr/iex/Start-Process/Out-File/redirect) ИЛИ psProtectedWrite
(P-3 forge-страж: PS-запись в ~/.claude/runtime / .env / секрет — иначе Set-Content
подделывает escape-грант). Escapable owner-санкцией. Реоткрытие v3.8 F1. 60 GREEN.

НАХОДКА РЕАЛИЗАЦИИ: plan-версия psProtectedWrite тестила whole-string SECRET_PATH_RE
с $-якорем → `.env` в позиции аргумента (-Path app/.env -Value …) терялся. Робастнее:
проверяем каждый токен (без кавычек, \→/) против anchored RUNTIME_RE/SECRET_PATH_RE —
runtime (forge-вектор) И secret-write закрыты, обычная запись не over-блокируется.
2026-06-08 09:09:18 +03:00
Дмитрий 7277584eaf harden(m7-floor): bashIsContentBlock рубит sub-shell как класс (sharp-edges после 1.3)
Строгий sharp-edges-гейт после Task 1.3 вскрыл класс обхода: подстрочный
matchBashHardBlacklist не де-обфусцирует command-substitution. Split-assembly
`$(echo no)$(echo de) -e x` и backtick `echo node` собирают интерпретатор только
при shell-eval → в сырой строке 'node' нет → content-block FALSE → пол пропускал.
router-gate ловит сейчас, но Фаза 8 (увольнение router-gate) открыла бы класс.

Закрытие: bashIsContentBlock проверяет detectSubshell(raw).found ($()/backtick/
process-subst/heredoc) → любой sub-shell = произвольное исполнение → content-block.
Независимо от parse-успеха. Escapable; router-gate тоже блокирует все sub-shell →
0 новых FP. Подтверждено: per-segment токенайзер де-обфусцирует n''ode/no\de.
114 GREEN (floor + enforce-floor + supreme-gate).
2026-06-08 09:06:23 +03:00
Дмитрий 89e9ca159e feat(m7-floor): floor-decide content-block ветка Bash (V1, escapable)
Task 1.3 Фазы 1 М7. bashIsContentBlock (whole+per-segment, паритет с bashIsFloor, P-4)
через единый matchBashHardBlacklist (P-1). floorDecide Bash-ветка зовёт content-block
ПЕРВЫМ (до bashIsFloor); escape снимает (owner-санкция). 44 GREEN.

НАХОДКА АУДИТА (задокументирована в коде+тесте): NB плана «echo "node -e foo" НЕ
over-блокируется» недостижим при подстрочном matchBashHardBlacklist (не отличает
опасную строку-аргумент echo от команды-интерпретатора). Решение — принять FP:
floor УЖЕ принял этот класс для `git push "--force"` (fail-safe, escapable);
under-block в полу страшнее over-block. Парсинг командной позиции НЕ вводим.
2026-06-08 09:01:04 +03:00
Дмитрий a5b62fbfad fix(m7-floor): canonicalAction +PowerShell — escape-привязка специфична (P-2)
Task 1.2b Фазы 1 М7 (КРИТ). canonicalAction получил ветку PowerShell:
`powershell:${normalizeCommand(command)}`. Без неё PS уходил в write-fallback,
пустой путь резолвился в cwd → один escape-грант разблокировал ЛЮБУЮ PS-команду
в окне (тест специфичности был зелёным ложно: a===b==='write:<cwd>').

Сквозной фикс: тот же canonicalAction зовут пол (Task 1.4), стена (enforce-supreme-gate)
и консьюмер. Bash/Write/mcp-ветки не задеты. 118 GREEN (escape-grant + 4 потребителя).
2026-06-08 08:56:44 +03:00
Дмитрий 91af38ca11 feat(m7-floor): powershell-destructive psContentBlock (V1-PS)
Task 1.2 Фазы 1 М7. Новый модуль tools/powershell-destructive.mjs — psContentBlock
для PowerShell-tool (PS-нативные глаголы Remove-Item/-Recurse/iwr/iex/Start-Process/
Out-File/redirect НЕ матчат unix-regex classify-destructive). Реоткрытие v3.8 F1:
PowerShell-tool был полностью вне scope content-floor. 16 GREEN.
2026-06-08 08:55:30 +03:00
Дмитрий 3847c863ca feat(m7-floor): classify-destructive +contentBlock (правило 8, V1 Bash)
Task 1.1 Фазы 1 М7. Поле contentBlock = matchBashHardBlacklist(cmd) !== null
(единый источник P-1, whole-string) рядом с floor/suspicious. suspicious ||=
contentBlock (P-5: голоса судьи М4 видят content-опасное). reason расширен.

Поле для видимости судьи; фактический блок пола — bashIsContentBlock
(whole+per-segment, Task 1.3). 71 GREEN (+38 content-block кейсов, incl.
P-1-пробелы env-prefix/--watch/2>file/cp/mv).
2026-06-08 08:53:53 +03:00
Дмитрий 1c251d2592 refactor(m7-floor): matchBashHardBlacklist -> shell-content-rules (единый дом content-правил, P-1)
Task 1.0.5 Фазы 1 М7. Перенос BASH_HARD_BLACKLIST + stderrRedirectBlock +
matchBashHardBlacklist из enforce-router-gate.mjs в постоянный дом
shell-content-rules.mjs (там уже живут hasInjection + matchAny). router-gate
ре-экспортирует их для обратной совместимости (тесты + тело гейта).

Единый источник правды устраняет port-дрейф content-floor (М5) по конструкции:
content-block пола (Task 1.1/1.3) импортирует ТОТ ЖЕ матчер, а не ручную копию.

Тесты: +describe single-source identity (router-gate BASH_HARD_BLACKLIST ===
shell-content-rules ссылка) + matchBashHardBlacklist hosted-in-SCR. 233 GREEN.
Чистый рефактор-перенос, 0 изменений семантики.
2026-06-08 08:51:31 +03:00
Дмитрий 15af97adae docs(m7): build-handoff #2 — состояние после фолжа разбора плана (HEAD 475d381e)
Готовый промт для новой сессии: подтвердить HEAD 475d381e, прочитать
handoff#2 + спеку §13 addendum + план Фазу 1 (Task 1.0.5-1.6), спросить
владельца, НИЧЕГО не делать самому. Заменяет handoff#1 (stale HEAD 8ba9a21c).
Карта правок P-1..P-8 (план↔спека). Код НЕ строили. commit-not-push.
2026-06-08 08:24:17 +03:00
Дмитрий 475d381e0c docs(m7): fold plan-critique findings P-1..P-8 into plan + spec
Independent critical review of the implementation plan (audit-context ->
sharp-edges -> variant-analysis -> systematic-debugging, grounded against
real M1-M6 code). 8 findings, all code-grounded, no ghosts:

- P-1 (CRIT): content-floor "full port" was a SUBSET of BASH_HARD_BLACKLIST
  (lost #21 env-prefix / #22 --watch / #34 echo-inj / C16 2>file /
  cp-mv-chmod-chown-chgrp; cp X ~/.claude/runtime = escape-grant forge)
  -> single source matchBashHardBlacklist relocated to shell-content-rules
  (Task 1.0.5) + §12 content-floor invariant proves completeness.
- P-2 (CRIT): canonicalAction has no PowerShell branch -> every PS command
  collapses to 'write:' -> one escape unlocks ALL PS commands; Task 1.5 test
  was spuriously green (both sides equally broken) -> Task 1.2b + specificity.
- P-3 (HIGH): PS floor branch returned block:false skipping runtime/secret
  guard (command field not parsed) -> Set-Content ~/.claude/runtime forge
  -> psProtectedWrite guard (Task 1.4).
- P-4 (MED): content-block whole-string only -> bashIsContentBlock whole+per
  -segment parity with bashIsFloor (Task 1.3).
- P-5 (MED): suspicious blind to content-danger -> suspicious |= contentBlock.
- P-6 (MED): §12 CI-invariants ownerless -> assigned per phase (phase rule).
- P-7 (LOW): Phase 0 fail-CLOSE "subset" unlisted -> explicit hook list.
- P-8 (LOW): plan = detailed Phase 1 + scoped skeleton -> honest framing.

Plan: Tasks 1.0.5/1.1/1.2b/1.3/1.4/1.5/1.6 + phase-transition rule + self-review.
Spec: §5 PowerShell row, §12 M5 line, §13 addendum.
No code built. commit-not-push.
2026-06-08 08:20:40 +03:00
Дмитрий eac1c45bbb docs(m7): build-handoff в новую сессию — состояние после критразбора + плана
Готовый промт для подхвата: HEAD 8ba9a21c, дизайн закрыт + критразбор/поправки
(b98b1885) + план (8ba9a21c). Next = сборка Фазы 1 (content-floor) инлайн TDD
по команде владельца. Квирки (vitest/git/junction/escape/грязь дерева) + жёсткие
правила (commit-not-push, субагенты запрещены, ничего не делать самому).
2026-06-08 07:56:45 +03:00
Дмитрий 8ba9a21c9c docs(m7): план реализации — мастер (фазы 0-8) + Фаза 1 (content-floor) детально
writing-plans по поправленной спеке М7. Scope-check: 9 подсистем →
dependency-ordered фазы 0-8. Фаза 1 (content-floor V1/V1-PS — критический
корень переезда, §10 запрещает увольнять router-gate до неё) в полной
bite-sized TDD-детализации (Task 1.0-1.6 с кодом); фазы 0,2-8 scoped,
разворачиваются в bite-sized при подходе. Self-review: spec coverage полон,
type-consistency проверена. Исполнение — инлайн (субагенты запрещены владельцем).
2026-06-08 07:53:03 +03:00
Дмитрий b98b18850a docs(m7): критический разбор спеки — поправки V1/V1-PS/SE-I/SE-C/SE-K/SE-D/SE-A/SE-B
Независимый критический разбор дизайна М7 (цепочка audit-context-building →
sharp-edges → variant-analysis → systematic-debugging). Фактология §2
подтверждена реальным кодом 8/8; sweep Класса 1 полон. Закрытия:

- V1/V1-PS (КРИТИЧНО): полный port BASH_HARD_BLACKLIST + PowerShell-набор в
  content-floor М5 (правило 8), блок независимо от плана. Иначе in-plan
  node -e / curl-exfil / npm install проскальзывали как шаг плана; node -e
  мог подделать escape-грант и подорвать машины изнутри.
- SE-I/L6: escape-survivability (правило 7) — тотальные canonicalAction/
  normalize, panic-ветка до per-tool-логики, чтение escape всеми остающимися
  fail-CLOSE-стражами (read-path-deny/mcp-classification/normative-content-rules).
- SE-C/SE-K: журнал-K2 честно ограничен skill:-каналом; +PostToolUse
  skill-журналер + seed-allow реактивных навыков (иначе seed/ad-hoc навыки
  в журнал не попадают).
- SE-D: граница КАРТА/ЗАКОН для .mjs через "покрыт ли правкой план-шаг"
  (build-loop не клинит, ad-hoc самомодификация требует escape).
- SE-A: §4.2 метки [Pre]/[Stop]. SE-B: манифест до полного набора М1-М6.
- §1 промис снабжён предпосылками П1/П2/П3 + 4-е структурное условие; §13 changelog.

Verify-item прошлого handoff закрыт фактом: enforce-parallel-session-lock = no-op.
Только спека (.md), код не трогался.
2026-06-08 07:48:13 +03:00
Дмитрий 9e7ca7ef19 docs(m7): дизайн Машины 7 — растворение зоопарка + непробиваемая дисциплина + полный переезд М1–М6
Design-doc (12 секций + само-аудит) + DONE-handoff дизайн-фазы.
Цепочка: audit-context-building + sharp-edges + variant-analysis + brainstorming.
Карта обходов дисциплины (6 классов + корень enforce-hook-helpers:7) → поглощение
в М1–М6 по 6 правилам (fail-CLOSE / PreToolUse / журнал-факт / escape-only / манифест / громко).
3 куска М7: зоопарк+дисциплина / normative-канал (карта свободно, закон — escape) / доска «кто на посту».
Реализация НЕ начата — ждёт ревью владельца → writing-plans. commit-not-push.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 07:06:00 +03:00
Дмитрий a0b98d227f docs(m6): DONE-handoff промт-блок — sync HEAD 8bfef418 + планка 2843+2 после пост-аудит фиксов
Промт для новой сессии теперь указывает актуальный HEAD и регрессионную планку; детали 4 фиксов — в разделе «Пост-аудит правки» + памяти.
2026-06-07 19:49:28 +03:00
Дмитрий 8bfef418c2 docs(m6): DONE-handoff — пост-аудит правки FIX-1..4 + DOC-1 (escape не сквозной через зоопарк)
Зафиксированы 4 аудит-фикса и caveat DOC-1: escape чтут только стена М2/пол М5/egress; router-gate / runtime-write-deny / судья М4 escape не знают → реальные разрушительные не пройдут до М7 (растворение зоопарка). Ожидаемо по §7.
2026-06-07 19:43:18 +03:00
Дмитрий d221ba499d fix(m6): аудит-правки — G-5 egress токен, единый findOpenGrant, escape-журнал, уникальный id снимка
Аудит М6 (audit-context-building + sharp-edges + корректность; комплекс М1–М6), 4 практичных фикса (TDD):
- FIX-1: enforce-mcp-classification печатает точный FLOOR-ESCAPE токен в egress/verdict-блоке (G-5 для egress).
- FIX-2: escape-grant.findOpenGrant — единый предикат свежести для open и consume (гасит ИМЕННО открывший грант; чинит утечку one-shot при дублях/future-ts).
- FIX-3: enforce-supreme-gate.runGate — best-effort журнал escape (escape:true), указатель не двигается, сбой журнала не блокирует.
- FIX-4: enforce-snapshot — уникальный дефолтный id снимка (ts-pid-счётчик) против ms-коллизии refs/floor-snapshots.

Регрессия tools-only 2843 passed + 2 skip (+9, 0 регрессий). FIX-5 (подпись гранта) сознательно не делали (нулевая защита без ключа; protected-path уже гарантирует).
2026-06-07 19:43:05 +03:00
Дмитрий 3ea34d42dd docs(router-mentor): M6 DONE-handoff — промт для новой сессии (пуш/активация/М7) 2026-06-07 19:14:43 +03:00
Дмитрий d0e0bd18c9 test(m6): сквозные инварианты escape + snapshot; регрессия зелёная (2834+2) 2026-06-07 19:04:57 +03:00
Дмитрий 28b92d90e6 feat(m6): enforce-snapshot — git-точка возврата перед разрушительным (fail-close) 2026-06-07 19:03:36 +03:00
Дмитрий a5b99eaa7e feat(m6): snapshot-decide — триггер снимка + чистое-дерево vs ошибка 2026-06-07 19:02:21 +03:00
Дмитрий 6e2d485f44 feat(m6): egress-escape — снятие egress-блока совпавшим floor_escape 2026-06-07 19:01:04 +03:00
Дмитрий b83cfc65b9 feat(m6): floor-escape-consume — одноразовое погашение пропуска (PostToolUse) 2026-06-07 18:58:32 +03:00
Дмитрий 4a10932cb6 feat(m6): G-1 сквозной escape в верховной стене М2 (allow без продвижения указателя) 2026-06-07 18:55:56 +03:00
Дмитрий d2109ac1dc feat(m6): пол — escape во всех ветках, замена approvalOpen 2026-06-07 18:52:34 +03:00
Дмитрий a9e8585767 feat(m6): писать floor_escape-пропуск из AskUser-ответа 2026-06-07 18:46:13 +03:00
Дмитрий 6b44e7afd8 feat(m6): toFloorEscapeRecord — распознавание escape-одобрения 2026-06-07 18:44:09 +03:00
Дмитрий 87d84a2e3f feat(m6): escape-grant pure core — canonicalAction + escapeGrantOpen + readers 2026-06-07 18:41:42 +03:00
Дмитрий 4f7b1fab09 docs(router-mentor): M6 build-handoff — промт для сессии реализации
Готовый промт для новой сессии: дерево/ветка, состояние (дизайн+план+аудит закрыты,
HEAD 20c85ede, регрессия 2789+2 skip, не запушено), что строим (escape сквозной
override + авто-снимок), порядок пакетов 1-9+4b, HARD-RULE скилов (executing-plans
инлайн, audit-context перед патчами, TDD, review, verification, regression),
жёсткие правила (commit-not-push), квирки (vitest/git-PowerShell/гейт/git restore не
в whitelist/tdd-gate/память-два-охранника/судья-нейтрально/coverage-verify/baseline 2789),
аудит уже сделан (G-1 α / G-2 / G-5 / G-6 / G-8 — не повторять), старт с Пакета 1.

Только handoff-артефакт, кода нет. Без push (commit-not-push).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 18:33:14 +03:00
Дмитрий 20c85ede09 docs(router-mentor): M6 аудит плана — G-1 α (escape сквозь стену М2) + G-2/G-5/G-6/G-8
Аудит плана реализации (writing-plans self-review + audit-context-building сквозь
М1–М5 + sharp-edges). Главная находка G-1: верховная стена М2 (enforce-supreme-gate
Δ7 + разговорный режим) блокирует разрушительное/мутаторы независимо от пола → floor_escape
(только пол) был no-op сквозь стену. Вариант α (решение владельца): escape — сквозной
override, чтимый стеной (allow без продвижения указателя), полом, egress.

Спек: §3 +enforce-supreme-gate, §4 блок G-1 (сквозной escape) + G-5/G-6/G-8, §9 +патч,
§11 аудит-таблица. План: новый Пакет 4b (стена М2, TDD), Пакет 4 +G-2 (переписать блок
двери) +G-5 (точный токен) +G-6 (запрет override), активация +supreme-gate, self-review.

Проверено ОК: экспорты совпадают, М1/М3/М4 не ломаются, общий канал askuser-decisions
фильтр по type. Только дизайн-артефакты, кода нет. Без push (commit-not-push).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 18:18:59 +03:00
Дмитрий 3fb7a0517f docs(router-mentor): M6 spec — синк floor-escape-consume из плана (one-shot PostToolUse)
При написании плана выяснилось: строгая одноразовость «погашение после реального
исполнения» (§4 F-S1) требует отдельного PostToolUse-консьюмера. Добавлены модули
floor-escape-consume.mjs (ядро) + enforce-floor-escape-consume.mjs (обёртка) в §3/§9,
уточнён §4 (погашение после исполнения → сбой снимка пропуск не тратит), §9 активация
+ PostToolUse, §11 поправка план→спек. Спек и план теперь совпадают.

Только дизайн-артефакт, кода нет. Без push (commit-not-push).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 18:01:05 +03:00
Дмитрий 719648cd08 docs(router-mentor): M6 implementation plan — escape + auto-snapshot (TDD пакеты 1-9)
План реализации Машины 6 по спеку 2026-06-07-router-mentor-machine-6-design.md.
9 пакетов, bite-sized TDD (RED→GREEN→commit), весь код в шагах, конвенции
(vitest абс-команда / commit через PowerShell / TDD-гейт / audit-context перед патчами).

Пакеты: 1 escape-grant ядро · 2 toFloorEscapeRecord · 3 писатель floor_escape ·
4 пол escape во всех ветках · 5 floor-escape-consume (one-shot, PostToolUse) ·
6 egress-escape · 7 snapshot-decide · 8 enforce-snapshot · 9 интеграция+регрессия.

NB: Пакет 5 вводит модуль floor-escape-consume, которого нет в инвентаре §9 спека —
операционализация одноразовости «погашение после исполнения»; отмечено в self-review,
к согласованию на ревью плана. Планка регрессии ≥ 2789 passed + 2 skip.

Только план-артефакт, кода нет. Без push (commit-not-push).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 17:57:01 +03:00
Дмитрий 47de8447dd docs(router-mentor): M6 design — факт-аудит кода, правки F1-F4/F-S1/F-S2/I1-I4
Аудит спека М6 тремя линзами (audit-context-building сверка с реальным кодом М5 +
sharp-edges; agentic-actions-auditor неприменим — CI-scope). Внесены правки:

F1  настоящий §4.5-парсер = askuser-answer-parser + enforce-askuser-answer-parser
    (не enforce-branch-switch).
F2  floor-набор разнесён на 3 локуса (Bash / Write-ветка / egress); escape на все три (B).
F3  binding = точное совпадение канонической строки (normalizeCommand / tool:pathNormalize
    / egress), не хеш над classifyDestructive (тот даёт булевы).
F4  toApprovalRecord git-only → migrate:fresh/db:wipe/.env были не одобряемы; floor_escape
    закрывает.
F-S1 escape = отдельный kind floor_escape + отдельный reader + one-shot консум
     (не переиспользование 5-мин approve_git_operation).
F-S2 снимок: чистое дерево → ref=HEAD (успех); fail-close только на реальную ошибку git.
I1-I4 переиспользование helper'ов / честный scope снимка / ясность runtime-записи хуком /
     фиксация неприменимости agentic-actions-auditor.

§11 — карта находка→правка. Только дизайн-артефакт, кода нет. Без push (commit-not-push).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 17:40:32 +03:00
Дмитрий d02932b053 docs(router-mentor): M6 design — escape + auto-snapshot (brainstorming)
Машина 6 (новая фаза дизайна эпика «роутер-наставник»): аварийный выход (escape)
+ авто-снимок (git-точка возврата). Достраивает безопасность пола М5.

Решения с владельцем: Р-М6-1 scope = escape + снимок (М7 = normative-канал /
растворение зоопарка / доска); Р-М6-2 escape = всплывающий вопрос (side-channel,
отпечаток-binding); Р-М6-3 escape на весь floor-список (B); Р-М6-4 снимок = git-
состояние (A); Р-М6-5 подход A (escape в floor-decide + отдельный enforce-snapshot).

Spec: docs/superpowers/specs/2026-06-07-router-mentor-machine-6-design.md.
Только дизайн-артефакт, кода нет. Без push (commit-not-push).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 17:15:20 +03:00
Дмитрий 32ffab621d docs(m6): handoff в новую сессию — М5 закрыта+переаудичена, М6 = новая фаза дизайна
Готовый промт: дерево/состояние (HEAD 849723bc, аудит М5 F-1/F-3/F-6 + F-2 память + F-4=C,
регрессия 2789+2 skip, не запушено) + шов М5<->М6 (spec §5 экспорт) + scope М6 (spec §6 YAGNI:
авто-снимок / портативный normative-канал / escape / растворение старых хуков; доска = М7) +
HARD-RULE скилов (brainstorming->writing-plans, инлайн, без суб-агентов) + квирки (vitest/git/
гейт/tdd/запись-в-память-два-охранника/судья-нейтральные-слова/baseline 2789) + хвосты М5.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 16:48:45 +03:00
Дмитрий 849723bc04 fix(m5): F-6 — нижняя граница времени в floor-decide approvalOpen
approvalOpen считал свежим одобрение с будущим ts (now - ts < 0 <= window) — часовой
сдвиг/подлог открывал дверь владельца. Добавлена нижняя граница now - ts >= 0: свежесть =
ts в прошлом И в пределах окна.

Аудит Машины 5 (объектив корректность). TDD RED->GREEN. Регрессия tools-only 2789 + 2 skip.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 16:18:44 +03:00
Дмитрий 7dd3a16531 fix(m5): F-3 — манифест floor-manifest-check проверяет весь защитный контур
DEFAULT_REQUIRED_HOOKS проверял только enforce-floor — owner мог зарегистрировать пол,
забыть верховную стену / exfil-стражей и получить зелёный «protected». Расширено до
security-load-bearing набора: enforce-floor + enforce-supreme-gate + normative-content
+ read-path-deny + mcp-classification. «Пол подтверждён» теперь = весь контур. WARN-only
(Δ8 — сигнал, не блок); owner может передать иной requiredHooks.

Аудит Машины 5 (объектив sharp-edges). TDD RED->GREEN. Регрессия tools-only 2789 + 2 skip.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 16:18:26 +03:00
Дмитрий 9c3205ad7c fix(m5): F-1 — убрать мёртвый контент-скан в enforce-read-path-deny
decide() гейтил по content в ветке, недостижимой в проде: enforce-read-path-deny —
PreToolUse(Read)-хук, main() не передавал content, а контента до чтения нет. Ветка
+ импорт scanSecrets убраны — decide() гейтит строго по пути (path-deny). Реальный
exfil (исходящий payload) закрыт живым enforce-mcp-classification.scanEgress; чтение
секрета само по себе не вынос.

Аудит Машины 5 (объектив sharp-edges + agentic-actions-auditor). TDD RED->GREEN.
Регрессия tools-only 2789 passed + 2 skip.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 16:18:05 +03:00
Дмитрий 2925d063fb docs(m5): handoff session-final — Машина 5 закрыта, финализация + продолжение эпика
Готовый промт для новой сессии: дерево + состояние (Пакеты 5-8 закрыты, 14 коммитов
24ce7b39..5d350b69, регрессия 2788+2skip, не запушено) + что осталось (finishing-branch под
«пуш» / память direct:memory-sync / активация владельцем) + HARD-RULE алгоритма скилов (запрет
нарушения, суб-агенты запрещены) + квирки (vitest/git/гейт/tdd-хуки/baseline 2788).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 15:35:17 +03:00
Дмитрий 5d350b6997 feat(m5): Пакет 8 — Δ3 честный двухтакт reconcile (8.1 пред-запись + 8.2 реконсилер)
Δ3: убрано обещание «атомарно на исполнении» (PreToolUse не видит факт). Достижимый максимум —
два такта:
- 8.1 (runGate): пред-запись НАМЕРЕНИЯ в журнал ДО allow. Журнал вернул false ИЛИ бросил →
  стена НЕ разрешает (block), указатель не двигается («нет записи → нет действия», явно).
  Backward-compat: push → length (truthy) = успех; только явный false/throw → block.
- 8.2 (enforce-reconcile.mjs, новый): PostToolUse-сверка. reconcileAction — исполненное
  действие без пред-записи → action-without-record (возможен обход). findOrphanIntents —
  пред-записи без исполнения → record-without-action. WARN-уровень (не блок: PreToolUse-пол
  уже отработал, PostToolUse не отменяет исполненное). Чистые функции + fail-quiet I/O main.

+2 (supreme-gate runGate) +5 (reconcile) тестов. Полная tools-only регрессия 2788 + 2 skip
(0 регрессий). Машина 5 (Пакеты 5-8) собрана полностью.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 15:29:48 +03:00
Дмитрий 7b2a3d32aa feat(m5): 7.6 инвариант разделения дисциплина/защита (Пакет 7, Блок 4.6)
Структурный guard-инвариант: модули защиты-пола GREEN (criterion-green, floor-signer)
не несут override-вокабуляра — мутация P18 + неподделываемый по-критерийный GREEN (Пакет 5)
это ЗАЩИТА (без override). tdd-gate остаётся ДИСЦИПЛИНОЙ (fail-open + override) в ОТДЕЛЬНОМ
хуке. Перенос мутации/GREEN-пола под override упадёт здесь. +positive control (не вакуумен).
7.7 (неподделываемый GREEN/RED) — закрыт Пакетами 3+5.

Guard-тест (prod-код не пишется; концепт реализован Пакетом 5). +3 теста.
Полная tools-only регрессия 2781 passed + 2 skip (0 регрессий). Пакет 7 завершён.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 15:24:52 +03:00
Дмитрий a88a80ed0b feat(m5): 7.5 parallel-session-lock pid-liveness (Пакет 7, дыра 5, Блок 4.5)
Закрыта дыра 5: свежий (не-stale) лок МЁРТВОГО держателя блокировал на весь TTL.
- isProcessAlive(pid): process.kill(pid,0) — ESRCH→мёртв, EPERM→жив; невалидный pid→мёртв.
- acquire +isPidAlive (инъектируемый): перехват, если держатель не жив (помимо stale/same-session).
  Без isPidAlive — backward-compat (старое поведение).
- runAcquireDecision +isPidAlive (default isProcessAlive) → acquire. Живой держатель → блок;
  мёртвый → перехват. Хук остаётся fail-open (availability, не защитный пол).

+5 (pure) +1 (wrapper) тестов; существующий «fresh lock» тест уточнён на живого держателя.
parallel-session-lock + enforce 27/27.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 15:23:15 +03:00
Дмитрий 4cfca9cc55 feat(m5): 7.4 workflow-gate inline-script + keychain-паттерны (Пакет 7, C5, Блок 4.4)
Закрыта дыра C5 (inline `script` был вне охвата → полный обход workflow-гейта):
- decide: inline `script` гейтится как scriptPath — скан DANGEROUS_PATTERNS + одобрение по
  sha256 контента (approve_workflow_script, 5-мин окно). Без одобрения → block.
- DANGEROUS_PATTERNS +keytar +get/set/delete/findPassword|Credentials(Sync) — контроллер
  не напишет workflow, читающий ключ подписанта/судьи из OS-keychain (действует и для scriptPath).
- main: при inline берёт content/sha256 из tool_input.script напрямую.
NB: regex-детектор eval()/child_process — паттерн-матчер, не вызов (header-коммент L19-21).

+5 тестов. enforce-workflow-gate 10/10.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 15:18:46 +03:00