feat: A - чтение под опечатанным планом свободно (ДР-1 снят в impl)
Под планом авторское чтение больше не блок: свой вывод, лог упавшего шага, новый файл доступны. Чтение не двигает очередь шагов; impl-чтения логируются с пометкой impl:true для ретро и не считаются во фронт-лоад порог. Секреты держит отдельный read-path-deny. Свод зелёный: 4221 passed, 2 skipped. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
# Дизайн: свободное чтение под опечатанным планом (снятие гейта ДР-1 в impl-режиме)
|
||||
|
||||
**Дата:** 2026-06-18 · **Репозиторий:** claude-brain (управляющий слой) · **Кодовая фраза:** «роутер-наставник».
|
||||
**Источник:** баги `bags/2026-06-17-wall-read-block-bug.md` (+ `bug1.md`). Пункт **A** роадмапа допила эталона.
|
||||
**Тип:** дизайн-доказательство (brainstorming → writing-plans). Правки `tools/*.mjs` — далее по церемонии TDD.
|
||||
|
||||
---
|
||||
|
||||
## 1. Проблема (по факту, с цитатами)
|
||||
|
||||
В режиме реализации (под опечатанным планом) чтение разрешено **только по пути текущего шага**.
|
||||
Всё прочее — блок, включая собственный вывод запущенных инструментов и файлы, появившиеся по ходу.
|
||||
|
||||
Корень — **одна строка**: [tools/reading-discipline.mjs:111-116](../../../tools/reading-discipline.mjs#L111-L116),
|
||||
функция `readingGateDecision`:
|
||||
|
||||
```
|
||||
if (kind !== 'authorial-raw') return { block: false … }; // граф-карта / путь шага / критик-проба — свободно
|
||||
if (frozenPlan) return { block: true, reason: '…гейт ДР-1 (impl-режим)' }; // ← ЭТО блокирует
|
||||
return { block: false … signal: true }; // разговорный режим — не блок, лог
|
||||
```
|
||||
|
||||
Вызывается из стены: [tools/enforce-supreme-gate.mjs:271-281](../../../tools/enforce-supreme-gate.mjs#L271-L281)
|
||||
(`decideReadEvent` → при `ev.gate.block` стена возвращает блок).
|
||||
|
||||
### Почему правило бьёт по работе (10 случаев из бага)
|
||||
Свой вывод сканера в temp-файле не прочитать; результат шага не проверить; ветвление по содержимому
|
||||
невозможно; диагностика по внешнему логу закрыта; файл, родившийся по ходу или от соседней сессии,
|
||||
недоступен. Итог — агент **действует вслепую**, чтобы не разворачивать план.
|
||||
|
||||
## 2. Что уже сделано (НЕ переделывать)
|
||||
|
||||
- **Десинк указателя F-J починен.** Стена двигает счётчик шага только при подтверждённом реальном шаге
|
||||
(двухтактная «предварительная пометка»): [enforce-supreme-gate.mjs:446-448](../../../tools/enforce-supreme-gate.mjs#L446-L448).
|
||||
Плюс floor-desync Δ7+: стена не двигает указатель на действие, которое зарубил бы пол
|
||||
([:315-323](../../../tools/enforce-supreme-gate.mjs#L315-L323)).
|
||||
- Следствие: **чтение и так не двигает очередь** (чтение никогда не было шагом). Поэтому открыть чтение
|
||||
безопасно — оно не может сдвинуть план. Главный риск из бага («наивный escape `read:` сдвинет очередь»)
|
||||
уже снят корнем.
|
||||
|
||||
## 3. Решение
|
||||
|
||||
**Во время реализации чтение не блокировать. Гейт ДР-1 из блокатора превращается в наблюдателя (лог).**
|
||||
|
||||
Обоснование (разобрано с владельцем 2026-06-18): запрет на чтение лечил не ту задачу и не в тот момент.
|
||||
Цель «прочитать всё для точной спеки» достигается **на этапе планирования**; после печати плана запрет
|
||||
ничего не добавляет к точности — только мешает проверять. Настоящая защита стены — **совпадение действия
|
||||
с шагом** (мутацию вне плана не выполнить), а не запрет чтения. Свободное чтение **не расширяет** набор
|
||||
разрешённых действий, поэтому безопасно; запрет же лишь заставляет действовать вслепую (слепой агент
|
||||
**опаснее** зрячего — не ловит свою ошибку).
|
||||
|
||||
### 3.1 Что меняем (ядро)
|
||||
1. **`readingGateDecision`** ([reading-discipline.mjs:111-116](../../../tools/reading-discipline.mjs#L111-L116)):
|
||||
ветка `if (frozenPlan) → block:true` заменяется на **не-блок с сигналом** (`block:false, signal:true`).
|
||||
В impl-режиме авторское сырьё-чтение становится **залогированным, но разрешённым**.
|
||||
2. **`recordRead`** ([reading-discipline.mjs:132-140](../../../tools/reading-discipline.mjs#L132-L140)):
|
||||
сейчас пишет в read-LOG только разговорное (`frozenPlan=false`) сырьё. Расширить: писать и impl-чтения
|
||||
(`frozenPlan=true`) с пометкой режима — чтобы ретро видело, что читалось под планом.
|
||||
3. **`enforce-supreme-gate`** (вызов на :271-281): после правки `ev.gate.block` для impl-сырья = false →
|
||||
чтение проходит. Отдельной правки стены, скорее всего, не нужно (она лишь чтит `ev.gate.block`) —
|
||||
подтвердить тестом интеграции.
|
||||
|
||||
### 3.2 Что НЕ трогаем (границы ответственности)
|
||||
- **Секрет-гарды.** Защита `.env`/паролей/секретов — **отдельный хук** (`read-path-deny` и секрет-сканеры),
|
||||
не гейт ДР-1. Он работает в обоих режимах независимо. Снятие ДР-1 его не ослабляет.
|
||||
- **Критик-проба наставника** (`MENTOR_PROBE_CAP=2/круг`, [reading-discipline.mjs:160-179](../../../tools/reading-discipline.mjs#L160-L179)) —
|
||||
про чтения САМОГО наставника, отдельный механизм. Не трогаем.
|
||||
- **Разговорный фронт-лоад-лог** (SE-R7-5, warn «много сырья до заморозки») — остаётся как есть.
|
||||
- **Машинерия шагов / указатель** — не касаемся (чтение не шаг).
|
||||
|
||||
### 3.3 Дисциплинарная заметка (норматив, не код)
|
||||
В Pravila/GUIDE добавить строку: *если чтение по ходу противоречит замыслу плана — честный ход
|
||||
«развернуть и перепланировать» (M7 Ф8 re-plan уже разрешён в impl), а не доделывать вслепую.* Стена это
|
||||
не заставит; ловят наставник/судья/ретро по логу чтений.
|
||||
|
||||
## 4. Критерий «починено» (из бага)
|
||||
- Под опечатанным планом читаются: свой вывод инструментов, файлы, созданные после печати, лог упавшего
|
||||
шага, файл соседней сессии — **без сдвига очереди шагов**.
|
||||
- Падение/блок шага НЕ двигает указатель (F-J — регресс-тест держит).
|
||||
- Секреты (`.env` и т.п.) по-прежнему закрыты `read-path-deny` (не регрессирует).
|
||||
- read-LOG фиксирует impl-чтения (видно в ретро).
|
||||
|
||||
## 5. Тесты (TDD-набросок)
|
||||
- `readingGateDecision({readKind:'authorial-raw', frozenPlan:true})` → `block:false, signal:true` (был true).
|
||||
- `readingGateDecision` для не-сырья — без изменений (граф-карта/путь шага/проба свободны).
|
||||
- `recordRead` пишет impl-чтение с пометкой режима; разговорное — как раньше.
|
||||
- Интеграция: под frozenPlan `decideReadEvent(authorial-raw)` → стена пускает Read (регресс на :271-281).
|
||||
- Регресс F-J: блок шага со-хуком не двигает указатель (уже есть — не ломаем).
|
||||
- Секрет-регресс: `.env` под планом всё равно режется отдельным гардом (smoke).
|
||||
|
||||
## 6. Решения владельца (закрыто 2026-06-18) + риски
|
||||
- **Q1 — РЕШЕНО: тихо.** impl-чтения логируются ТОЛЬКО для ретро, в баннер не выводятся.
|
||||
- **Q2 — РЕШЕНО: порога-warn нет.** Чтение под планом легитимно — число не ограничиваем и не пугаем.
|
||||
- Риск «дрейфа» (читаю и тихо доделываю кривой план вместо re-plan) держится не кодом, а
|
||||
шаг-гейтом (off-plan действие не пройдёт) + дисциплинарной заметкой §3.3.
|
||||
Reference in New Issue
Block a user