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.
This commit is contained in:
@@ -123,3 +123,40 @@ a5b99eaa feat(m6): snapshot-decide — триггер снимка + чисто
|
||||
28b92d90 feat(m6): enforce-snapshot — git-точка возврата перед разрушительным (fail-close)
|
||||
d0e0bd18 test(m6): сквозные инварианты escape + snapshot; регрессия зелёная (2834+2)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Пост-аудит правки (2026-06-07, отдельная сессия — аудит М6 + 4 фикса; commit-not-push)
|
||||
|
||||
Аудит М6 шестью осями (`audit-context-building` + `sharp-edges` + корректность логики; +комплекс М1–М6).
|
||||
Вывод: архитектурно верно, швы М1–М5 целы. Внесены 4 практичных фикса (TDD RED→GREEN, регрессия
|
||||
tools-only **2843 passed + 2 skip**, +9 тестов, 0 регрессий):
|
||||
|
||||
- **FIX-1 (G-5 egress):** `enforce-mcp-classification` печатает в блок-сообщении точную канон-строку
|
||||
`… ; FLOOR-ESCAPE: mcp:<tool>:<json>` (раньше токен выводил только пол Bash/Write; egress оставался
|
||||
без точной строки для AskUser → владелец не получал, что вставлять).
|
||||
- **FIX-2 (единый предикат свежести):** в `escape-grant` вынесен `findOpenGrant`; `escapeGrantOpen` и
|
||||
`floor-escape-consume.consumeDecision` гасят ИМЕННО открывший грант. Раньше при дублях/future-ts
|
||||
consume мог пометить «не тот» грант → утечка one-shot (тест воспроизводил баг → закрыт).
|
||||
- **FIX-3 (журнал escape):** `enforce-supreme-gate.runGate` пишет escape best-effort в журнал
|
||||
намерений (`escape:true`), указатель НЕ двигается; сбой/отсутствие журнала escape НЕ блокирует
|
||||
(escape санкционирован владельцем). Снимает будущий false-positive реконсилера «action-without-record
|
||||
(обход стены)» для легитимного escape.
|
||||
- **FIX-4 (уникальный снимок):** `enforce-snapshot` дефолтный id = `ts-pid-счётчик` (раньше два
|
||||
разрушительных в одну ms клобберили один `refs/floor-snapshots/<id>`).
|
||||
|
||||
**FIX-5 (подпись гранта) сознательно НЕ делали:** в штатном «без ключа» режиме reader обязан принимать
|
||||
неподписанное (иначе escape ломается у всех) → защиты нет; protected-path уже гарантирует целостность.
|
||||
Спек §6 пометил её «не обязательно».
|
||||
|
||||
### ⚠️ DOC-1 — escape НЕ сквозной через старый «зоопарк» (важно ПЕРЕД активацией)
|
||||
escape чтут **только** стена М2 / пол М5 / egress. Параллельные стражи живой среды —
|
||||
`enforce-router-gate` (default-deny whitelist; блокирует мутирующий git/bash — он в этой сессии
|
||||
заблокировал даже `git log`), `enforce-runtime-write-deny` (блок Write в `~/.claude/runtime`) и судья
|
||||
М4 (когда активируют) — escape **не знают** и заблокируют то же действие. Значит после активации М6
|
||||
реальный `git push --force` / запись в `.env` всё равно не пройдут, пока эти хуки зарегистрированы.
|
||||
Полностью «дверь открывается» только когда М7 растворит/научит зоопарк (или владелец деригистрирует
|
||||
router-gate/runtime-write-deny). Это **ожидаемо по §7 (YAGNI→М7)**, но держать в голове: М6 — дверь в
|
||||
стене М2/М5/egress, не во всей обороне.
|
||||
|
||||
**Изменённые файлы (10, commit-not-push):** `tools/{escape-grant,floor-escape-consume,enforce-mcp-classification,enforce-snapshot,enforce-supreme-gate}.mjs` + их `.test.mjs`.
|
||||
|
||||
Reference in New Issue
Block a user