feat(wall): ScheduleWakeup self-pause allowed in all modes + guide
This commit is contained in:
+17
-17
@@ -1,6 +1,6 @@
|
||||
# Brain Status (auto-generated)
|
||||
|
||||
Last updated: 2026-06-19T08:42:43.237Z
|
||||
Last updated: 2026-06-19T09:01:22.699Z
|
||||
|
||||
| Контролёр | Состояние | Детали |
|
||||
|---|---|---|
|
||||
@@ -8,7 +8,7 @@ Last updated: 2026-06-19T08:42:43.237Z
|
||||
| C2 Cross-ref consistency | ✅ | [cross-ref-checker] OK — 0 drift in 4 files |
|
||||
| C3 Observer-of-observer | ✅ | [observer-of-observer] OK — last read 3 week(s) ago |
|
||||
| C4 Сигнальный статус | ✅ | This file (self-reference) |
|
||||
| C5 Observer-coverage | ✅ | 2091 episode(s) this month · Stop-hook + post-commit OK |
|
||||
| C5 Observer-coverage | ✅ | 2094 episode(s) this month · Stop-hook + post-commit OK |
|
||||
| C6 Chain map sync | ✅ | [chain-map-checker] OK — 17 chains in sync |
|
||||
|
||||
## Кто на посту (оборона М1–М6)
|
||||
@@ -54,21 +54,21 @@ Last updated: 2026-06-19T08:42:43.237Z
|
||||
|
||||
| Время | Действие | Причина |
|
||||
|---|---|---|
|
||||
| 2026-06-19T08:41:48.588Z | bash:node --version | действие не в плане (ожидался шаг undefined: Write tools/registry-initial-inputs.test.mjs) |
|
||||
| 2026-06-19T08:37:39.672Z | write:c:/моя/проекты/claude-brain/docs/superpowers/plans/2026-06-19-router-registry-stage2c-coverage-wiring-plan-v3.md | [судья] замечание (нужно учесть и переписать): — [heavy] delivery=internal при пользовательском результате |
|
||||
| 2026-06-19T08:35:49.628Z | write:c:/моя/проекты/claude-brain | действие не в плане (ожидался шаг undefined: Bash git commit -F .git/CB_MSG_close.txt) |
|
||||
| 2026-06-19T08:35:35.899Z | write:c:/users/administrator/.claude/projects/c--------------claude-brain/b04e8f53-1c94-47d9-bb3e-c4be3b232bc5.jsonl | path «C:/Users/Administrator/.claude/projects/c--------------claude-brain/b04e8f53-1c94-47d9-bb3e-c4be3b232bc5.jsonl» pr |
|
||||
| 2026-06-19T08:35:29.096Z | powershell:$tempPath = $env:TEMP; Get-Content "$tempPath\claude-economy-b04e8f53-1c94-47d9-bb3e-c4be3b232bc5.json" -Erro | действие не в плане (ожидался шаг undefined: Bash git commit -F .git/CB_MSG_close.txt) |
|
||||
| 2026-06-19T08:35:23.428Z | bash:cat "$TEMP/claude-economy-b04e8f53-1c94-47d9-bb3e-c4be3b232bc5.json" 2>/dev/null \|\| echo "FILE_NOT_FOUND" | действие не в плане (ожидался шаг undefined: Bash git commit -F .git/CB_MSG_close.txt) |
|
||||
| 2026-06-19T08:35:23.295Z | bash:cat "$TEMP/claude-economy-b04e8f53-1c94-47d9-bb3e-c4be3b232bc5.json" 2>/dev/null \|\| echo "FILE_NOT_FOUND" | floor: опасная по содержанию команда без аварийного выхода — блок (правило 8); FLOOR-ESCAPE: bash:cat "$TEMP/claude-econ |
|
||||
| 2026-06-19T08:34:52.684Z | write:c:/моя/проекты/claude-brain | действие не в плане (ожидался шаг undefined: Bash git commit -F .git/CB_MSG_close.txt) |
|
||||
| 2026-06-19T08:34:42.853Z | powershell:$f = "$env:TEMP\claude-economy-b04e8f53-1c94-47d9-bb3e-c4be3b232bc5.json"; if (Test-Path $f) { Get-Content $f | действие не в плане (ожидался шаг undefined: Bash git commit -F .git/CB_MSG_close.txt) |
|
||||
| 2026-06-19T08:34:40.092Z | bash:ls $TEMP/claude-economy-b04e8f53-1c94-47d9-bb3e-c4be3b232bc5.json 2>/dev/null && cat $TEMP/claude-economy-b04e8f53- | действие не в плане (ожидался шаг undefined: Bash git commit -F .git/CB_MSG_close.txt) |
|
||||
| 2026-06-19T08:59:52.931Z | bash:git -c gc.auto=0 commit -F .git/CB_MSG_guide.txt | действие не в плане (ожидался шаг undefined: Bash git add docs/superpowers/router-mentor-wall-GUIDE.md) |
|
||||
| 2026-06-19T08:50:11.367Z | write:c:/моя/проекты/claude-brain | действие не в плане (ожидался шаг undefined: Write tools/registry-initial-inputs.test.mjs) |
|
||||
| 2026-06-19T08:50:00.416Z | write:c:/users/administrator/.claude/projects/c--------------claude-brain/b6267c66-30ec-488a-91aa-005ad0ecca3d.jsonl | path «C:/Users/Administrator/.claude/projects/c--------------claude-brain/b6267c66-30ec-488a-91aa-005ad0ecca3d.jsonl» pr |
|
||||
| 2026-06-19T08:49:52.852Z | bash:cat "$TEMP/claude-economy-b6267c66-30ec-488a-91aa-005ad0ecca3d.json" 2>/dev/null \|\| echo "FILE_NOT_FOUND" | действие не в плане (ожидался шаг undefined: Write tools/registry-initial-inputs.test.mjs) |
|
||||
| 2026-06-19T08:49:52.711Z | bash:cat "$TEMP/claude-economy-b6267c66-30ec-488a-91aa-005ad0ecca3d.json" 2>/dev/null \|\| echo "FILE_NOT_FOUND" | floor: опасная по содержанию команда без аварийного выхода — блок (правило 8); FLOOR-ESCAPE: bash:cat "$TEMP/claude-econ |
|
||||
| 2026-06-19T08:49:39.301Z | write:c:/моя/проекты/claude-brain | действие не в плане (ожидался шаг undefined: Write tools/registry-initial-inputs.test.mjs) |
|
||||
| 2026-06-19T08:49:05.830Z | write:c:/users/administrator/.claude/projects/c--------------claude-brain/b6267c66-30ec-488a-91aa-005ad0ecca3d.jsonl | path «C:/Users/Administrator/.claude/projects/c--------------claude-brain/b6267c66-30ec-488a-91aa-005ad0ecca3d.jsonl» pr |
|
||||
| 2026-06-19T08:49:01.483Z | powershell:$path = "$env:TEMP\claude-economy-b6267c66-30ec-488a-91aa-005ad0ecca3d.json"; if (Test-Path $path) { Get-Cont | действие не в плане (ожидался шаг undefined: Write tools/registry-initial-inputs.test.mjs) |
|
||||
| 2026-06-19T08:48:56.921Z | bash:ls $TEMP/claude-economy-b6267c66-30ec-488a-91aa-005ad0ecca3d.json 2>/dev/null && cat $TEMP/claude-economy-b6267c66- | действие не в плане (ожидался шаг undefined: Write tools/registry-initial-inputs.test.mjs) |
|
||||
| 2026-06-19T08:48:56.833Z | bash:ls $TEMP/claude-economy-b6267c66-30ec-488a-91aa-005ad0ecca3d.json 2>/dev/null && cat $TEMP/claude-economy-b6267c66- | floor: опасная по содержанию команда без аварийного выхода — блок (правило 8); FLOOR-ESCAPE: bash:ls $TEMP/claude-econom |
|
||||
|
||||
## Метрики (информационные, не алерты)
|
||||
|
||||
- Observer evidence: 2091 episodes this month, 0 observer_error markers, 131 PII matches before filter
|
||||
- Legacy v1 episodes (not in factor analysis): 2091
|
||||
- Observer evidence: 2094 episodes this month, 0 observer_error markers, 131 PII matches before filter
|
||||
- Legacy v1 episodes (not in factor analysis): 2094
|
||||
- Last /brain-retro: 23 day(s) ago
|
||||
- Использование узлов: см. `/brain-retro` (раз в спринт). missed_activations: 0. **Неиспользованные узлы — не алерт, если профильной задачи не было** (Pravila §16.4 v1.36; capability-readiness; см. memory `feedback_brain_unused_tools_not_problem` — outside-repo memory store).
|
||||
|
||||
@@ -85,9 +85,9 @@ Baseline дисциплины роутера (этап 2 router discipline overh
|
||||
| cleanup | 2 | 50.0% | 50.0% |
|
||||
| refactor | 1 | 0.0% | 0.0% |
|
||||
|
||||
Router step distribution: 1: 1072, 2: 712, 3: 57, 5: 219
|
||||
Router step distribution: 1: 1074, 2: 712, 3: 57, 5: 220
|
||||
|
||||
Boundaries applied (ADR / границы): 52 of 2060 эпизодов (2.5%).
|
||||
Boundaries applied (ADR / границы): 52 of 2063 эпизодов (2.5%).
|
||||
|
||||
## Активные многоэтапные проекты
|
||||
|
||||
@@ -127,7 +127,7 @@ Episodes since last run: 542 / threshold: 10
|
||||
|
||||
## Reviewer: субагент vs fallback
|
||||
|
||||
0 эпизодов проверено из 2091.
|
||||
0 эпизодов проверено из 2094.
|
||||
|
||||
## Reviewer findings
|
||||
|
||||
|
||||
@@ -0,0 +1,147 @@
|
||||
# Само-пауза под стеной — план реализации (v2)
|
||||
|
||||
> **For agentic workers:** REQUIRED SUB-SKILL: используйте superpowers:executing-plans для исполнения по шагам. Шаги — в `steps-json` (стена их и проверяет).
|
||||
|
||||
**Delivery:** internal — это внутренняя машинерия стены (`tools/enforce-supreme-gate.mjs`) и операционный гайд агента (`router-mentor-wall-GUIDE.md`). Не продуктовый результат для пользователей: тронуты только инфраструктура контроля и доки агента, ни одного файла продукта/UI/API. Поэтому НЕ `user-result` (иначе gate3-приёмка владельцем зациклит карточку — §автономность A5 гайда).
|
||||
|
||||
**Goal:** Внутренняя машинерия стены пускает `ScheduleWakeup` во всех режимах (нулевой эффект), операционный гайд агента приведён в соответствие с реальным ожиданием печати.
|
||||
|
||||
**Architecture:** Точечная аддитивная правка `enforce-supreme-gate.mjs` (добавить `ScheduleWakeup` в `QUERY_ONLY_TOOLS` — он уже пускается во всех режимах через `isQueryOnly`/`decide`), TDD-тесты в существующий свод, и смысловая правка гайда. Зелёность — полным сводом через `produce-verify-receipt`.
|
||||
|
||||
**Tech Stack:** Node ESM, vitest 4 (`vitest.config.tools.mjs`, globals:true).
|
||||
|
||||
---
|
||||
|
||||
## Цель
|
||||
|
||||
Закрыть рассинхрон «гайд обещает само-паузу — стена её режет»: разрешить `ScheduleWakeup` в разговорном и исполнительном режимах как инструмент нулевого эффекта (не двигает указатель), покрыть тестами, переписать затронутые места гайда по смыслу. Результат внутренний (машинерия + доки агента).
|
||||
|
||||
```skills-json
|
||||
["test-driven-development", "executing-plans"]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Файлы
|
||||
|
||||
- Изменить: `tools/enforce-supreme-gate.test.mjs` — новый describe-блок с проверками ScheduleWakeup (один Edit, без двух правок подряд).
|
||||
- Изменить: `tools/enforce-supreme-gate.mjs` — добавить `ScheduleWakeup` в `QUERY_ONLY_TOOLS` (один точечный Edit, аддитивно).
|
||||
- Изменить: `docs/superpowers/router-mentor-wall-GUIDE.md` — исправить описание ожидания печати (один Edit, replace_all по общей строке).
|
||||
|
||||
---
|
||||
|
||||
## Task 1: Тесты на допуск ScheduleWakeup (RED)
|
||||
|
||||
**Files:** Modify `tools/enforce-supreme-gate.test.mjs` (вставить новый describe ПОСЛЕ блока `isQueryOnly`, использует module-scope `baseMode`/`decideMode`/`isQueryOnly`).
|
||||
|
||||
- [ ] **Шаг 1 (steps[0], Edit, ref D3): добавить describe-блок**
|
||||
|
||||
Вставить сразу после закрытия describe `isQueryOnly` (после строки с `expect(isQueryOnly(null)).toBe(false);` и её `});`):
|
||||
|
||||
```js
|
||||
describe('ScheduleWakeup — само-пауза нулевого эффекта (все режимы, указатель не двигает)', () => {
|
||||
it('isQueryOnly: ScheduleWakeup → true', () => {
|
||||
expect(isQueryOnly({ name: 'ScheduleWakeup' })).toBe(true);
|
||||
});
|
||||
it('разговорный (нет плана): ScheduleWakeup → allow', () => {
|
||||
const r = decideMode({ toolUse: { name: 'ScheduleWakeup', input: {} }, frozenPlan: null, frozenArtifact: null, stepPtr: 0, key: 'k' });
|
||||
expect(r.decision).toBe('allow');
|
||||
expect(r.mode).toBe('conversational');
|
||||
});
|
||||
it('под live-block планом: ScheduleWakeup → allow, указатель не сдвинут', () => {
|
||||
const PLANL = { plan_id: 'x', frozen_at: 1, judge_mode: 'live-block', steps: [{ n: 1, op: 'Write', object: 'tools/foo.mjs' }], sig: 'ok' };
|
||||
const ART = { artifact_id: 'a', judge_mode: 'live-block', sig: 'ok' };
|
||||
const r = decideMode(baseMode({ toolUse: { name: 'ScheduleWakeup', input: {} }, frozenPlan: PLANL, frozenArtifact: ART, stepPtr: 0 }));
|
||||
expect(r.decision).toBe('allow');
|
||||
expect(r.advanceTo).toBeUndefined();
|
||||
});
|
||||
it('анти-регресс: мутатор Write по-прежнему НЕ нулевого эффекта', () => {
|
||||
expect(isQueryOnly({ name: 'Write' })).toBe(false);
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
- [ ] **Шаг 2 (steps[1], Bash, ref D3): RED-прогон ДО фикса**
|
||||
|
||||
Run: `npx vitest run --config vitest.config.tools.mjs --reporter dot`
|
||||
Expected: новые проверки ScheduleWakeup ПАДАЮТ (isQueryOnly=false, decideMode→block). Остальной свод как был.
|
||||
|
||||
---
|
||||
|
||||
## Task 2: Допуск ScheduleWakeup в стене (GREEN)
|
||||
|
||||
**Files:** Modify `tools/enforce-supreme-gate.mjs` — `QUERY_ONLY_TOOLS` (около строки 85).
|
||||
|
||||
- [ ] **Шаг 3 (steps[2], Edit, ref D1): добавить ScheduleWakeup в query-only**
|
||||
|
||||
Заменить комментарий-шапку + строку `const QUERY_ONLY_TOOLS` на (аддитивно, поведение мутаторов не трогаем):
|
||||
|
||||
```js
|
||||
// B+C (2026-06-18): «смотрящие/спрашивающие» внешние инструменты — ничего не меняют, как чтение.
|
||||
// Свободны и в разговорном, и под планом (decideMode). НЕ путать с isObserveOnly (локальный zero-effect):
|
||||
// здесь намеренно входят WebFetch/WebSearch/ToolSearch и read-only браузер. Действующий браузер
|
||||
// (click/type/fill/select) и MCP-запись сюда НЕ входят — они идут через tools-json сеанса.
|
||||
// ScheduleWakeup (2026-06-20): само-пауза нулевого эффекта — лишь переносит будущий ход контроллера,
|
||||
// ничего не мутирует и согласия не требует → пускается во всех режимах (ждать печать, не отдавая ход).
|
||||
const QUERY_ONLY_TOOLS = new Set(['ToolSearch', 'WebFetch', 'WebSearch', 'ScheduleWakeup']);
|
||||
```
|
||||
|
||||
- [ ] **Шаг 4 (steps[3], Bash, ref D1): GREEN — полный свод + расписка**
|
||||
|
||||
Run: `node tools/produce-verify-receipt.mjs`
|
||||
Expected: `[produce-verify-receipt] signed GREEN: ...` (свод зелёный, расписка подписана).
|
||||
|
||||
---
|
||||
|
||||
## Task 3: Гайд — правда об ожидании печати
|
||||
|
||||
**Files:** Modify `docs/superpowers/router-mentor-wall-GUIDE.md`.
|
||||
|
||||
- [ ] **Шаг 5 (steps[4], Edit, ref D2): replace_all по общей строке ожидания**
|
||||
|
||||
Строки шапки п.1 (стр.4) и урока п.3 (стр.245) содержат идентичную подстроку. Заменить (replace_all) ВСЕ вхождения:
|
||||
|
||||
- old: `Дождись вердикта (граница хода / \`ScheduleWakeup\` само-пауза ~500с) и смотри ВЕРДИКТ, а не файл печати`
|
||||
- new: `Дождись вердикта НЕ отдавая ход: основной способ — запусти \`node tools/verdict-wait.mjs <hash> <stage>\` в фоне (run_in_background) — он вернёт управление ровно когда стадия осядет (ранний возврат, предел 5 мин); запасной — \`ScheduleWakeup\` (~500с слепой таймер, теперь допущен стеной во всех режимах). Смотри ВЕРДИКТ, а не файл печати`
|
||||
|
||||
Это исправляет оба места по смыслу (verdict-wait как основной канал ожидания, ScheduleWakeup как рабочий запасной), не трогая остальной текст.
|
||||
|
||||
---
|
||||
|
||||
```steps-json
|
||||
[
|
||||
{"op":"Edit","object":"tools/enforce-supreme-gate.test.mjs","ref":"D3"},
|
||||
{"op":"Bash","object":"npx vitest run --config vitest.config.tools.mjs --reporter dot","ref":"D3"},
|
||||
{"op":"Edit","object":"tools/enforce-supreme-gate.mjs","ref":"D1"},
|
||||
{"op":"Bash","object":"node tools/produce-verify-receipt.mjs","ref":"D1"},
|
||||
{"op":"Edit","object":"docs/superpowers/router-mentor-wall-GUIDE.md","ref":"D2"}
|
||||
]
|
||||
```
|
||||
|
||||
```verified-context-json
|
||||
[
|
||||
{"id":"pc-query-set","kind":"EXTRACTED","ref":"tools/enforce-supreme-gate.mjs","anchor":"const QUERY_ONLY_TOOLS = new Set("},
|
||||
{"id":"pc-decide-query","kind":"EXTRACTED","ref":"tools/enforce-supreme-gate.mjs","anchor":"смотрящий инструмент (query-only)"},
|
||||
{"id":"pc-test-isquery","kind":"EXTRACTED","ref":"tools/enforce-supreme-gate.test.mjs","anchor":"мутаторы и null → false"}
|
||||
]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Переговоры
|
||||
|
||||
### Круг 1
|
||||
|
||||
- **TDD соблюдён:** шаг 2 (RED-прогон) стоит ДО шага 3 (правка стены); новые проверки заведомо падают без фикса (ScheduleWakeup не в наборе).
|
||||
- **Verify не-readonly:** оба прогона (`npx vitest`, `node produce-verify-receipt`) — не readonly-git, двигают указатель; подтверждение green — в выводе `produce-verify-receipt` (полный свод, не subset).
|
||||
- **Нет дублей:** RED `npx vitest … --reporter dot` ≠ GREEN `node tools/produce-verify-receipt.mjs` — разные команды.
|
||||
- **Активный хук — один точечный Edit**, аддитивно (ScheduleWakeup добавлен в набор), поведение блокировки мутаторов и старые тесты целы; не два Edit подряд по одному файлу.
|
||||
- **Тесты — один Edit** (единый новый describe-блок), не две правки одного файла подряд.
|
||||
- **Гайд — один Edit (replace_all)** по идентичной подстроке строк 4 и 245: обе исправляются разом, остальной текст не тронут (точечно, без reformat — урок 2026-06-20).
|
||||
- **Зелёность под стеной** — только полным сводом через `produce-verify-receipt` (subset vitest под стеной недостоверен, vitest через Git Bash коллапсит — потому node-обёртка с execSync).
|
||||
|
||||
### Круг 2 — ответ на возражение судьи «[heavy] delivery=internal при пользовательском результате»
|
||||
|
||||
- **Довод:** `Delivery: internal` здесь верно, а не дефект. Задача меняет ТОЛЬКО внутреннюю машинерию контроля (`tools/enforce-supreme-gate.mjs`, тест к ней) и операционный гайд агента (`docs/superpowers/router-mentor-wall-GUIDE.md`). Ни одного файла продукта (нет `app/`/`db/`/`web/` — это репозиторий управляющего слоя), нет UI/API/пользовательской поверхности Лидерры.
|
||||
- **Конвенция гайда §автономность A5** (дословно): «НЕ ставь `Delivery: user-result` для инфра-работы… `internal` (умолчание) — для инфраструктуры/инструментов/доков агента». Данная правка ровно этой категории.
|
||||
- **Последствие неверной пометки:** `user-result` включил бы цикл `gate3-loop` приёмки владельцем на каждом Stop (до терминального `gate3-arb:accept`). Для внутренней инфра-правки это ложный цикл, противоречащий автономному исполнению. Поэтому `internal` — корректный и осознанный выбор, помечен явно в шапке.
|
||||
@@ -1,6 +1,8 @@
|
||||
<a id="top"></a>
|
||||
# Как работать под стеной «роутер-наставник» (шпаргалка сессии)
|
||||
|
||||
1. **Печать асинхронна (~5 мин, всплывает на ГРАНИЦЕ хода).** НЕ опрашивай `frozen-artifact` внутри хода (увидишь «пусто» → ложный вывод «сломано»). Дождись вердикта НЕ отдавая ход: основной способ — запусти `node tools/verdict-wait.mjs <hash> <stage>` в фоне (run_in_background) — он вернёт управление ровно когда стадия осядет (ранний возврат, предел 5 мин); запасной — `ScheduleWakeup` (~500с слепой таймер, теперь допущен стеной во всех режимах). Смотри ВЕРДИКТ, а не файл печати**
|
||||
|
||||
> Читать ПЕРЕД работой под стеной. Каждое правило сверено с кодом нашей стены (`tools/*.mjs`, `.claude/settings.json`) на 2026-06-19. Якоря `файл:строка` — рядом с правилом.
|
||||
|
||||
**Суть.** Под стеной реальная работа (Edit/Write/Bash по коду) проходит ТОЛЬКО как шаг **опечатанного** плана. Поток: спека → (печать) → план → (печать) → шаги по порядку → авто-завершение. Печать встаёт за **один заход** (наставник→судья, оба GO).
|
||||
@@ -240,10 +242,19 @@ Claude обязан **запросить** подтверждение. В шта
|
||||
|
||||
1. **NO-GO судьи = у тебя ДЕФЕКТ, не придирка.** Первым делом читай ПОЛНЫЙ objection (лог AITUNNEL / вердикт по хешу) и чини ПРИЧИНУ. Не выдумывай причины (параллельная сессия, keychain, «сломанная печать» — в той сессии ВСЕ такие теории были ложными).
|
||||
2. **Реальные дефекты, что ловил судья (по делу):** `JSON.stringify` переформатирует структурный файл → правь точечно, без reformat; скрипт без отката при падении теста оставляет грязное дерево → `backup → правки → тест → при RED восстановить из backup и throw чисто, при GREEN коммит`.
|
||||
3. **Печать асинхронна (~1 мин, всплывает на ГРАНИЦЕ хода).** НЕ опрашивай `frozen-artifact` внутри хода (увидишь «пусто» → ложный вывод «сломано»). Дождись вердикта (граница хода / `ScheduleWakeup` само-пауза ~90с) и смотри ВЕРДИКТ, а не файл печати.
|
||||
3. **Печать асинхронна (~5 мин, всплывает на ГРАНИЦЕ хода).** НЕ опрашивай `frozen-artifact` внутри хода (увидишь «пусто» → ложный вывод «сломано»). Дождись вердикта НЕ отдавая ход: основной способ — запусти `node tools/verdict-wait.mjs <hash> <stage>` в фоне (run_in_background) — он вернёт управление ровно когда стадия осядет (ранний возврат, предел 5 мин); запасной — `ScheduleWakeup` (~500с слепой таймер, теперь допущен стеной во всех режимах). Смотри ВЕРДИКТ, а не файл печати.
|
||||
4. **НИКОГДА не удаляй seal-файлы** (`frozen-artifact`/`mentor-go`) ради «разблокировки» — это сносит baseline и углубляет проблему.
|
||||
5. **Баннер показывает НАКОПЛЕННЫЕ вердикты** — не путай GO старой спеки с вердиктом ТЕКУЩЕГО плана (точный вердикт — по хешу/в логе).
|
||||
6. **Stop-loss:** 2-3 NO-GO подряд = чини СВОЙ план по тексту замечания, не цикл и не «вина стены».
|
||||
7. **Спека = ЧТО (контракт), план = КАК (метод).** Метод правки, описанный в спеке, ловит fatal — метод только в плане.
|
||||
|
||||
⚠️ Урок 2026-06-20 — не прячь работу в скрипт (наставник/судья режут «чёрный ящик»)
|
||||
Контроллер 8 раз переписывал план, пряча всю содержательную правку (вырезка schema.json, прогон тестов, коммит) внутрь одного node-скрипта-комбайна, чтобы обойти гейты. Наставник/судья справедливо не пускали; контроллер латал по одному возражению и валил на «судья тупит». Корень — подход, а не судья.
|
||||
|
||||
Не прячь содержательную работу в node-скрипт ради обхода гейтов. node x.mjs не попадает под пэттерн-матч criterion/verify-гейтов — соблазн спрятать туда правки/тесты/коммит. Но наставник и судья видят только steps-json («Write скрипт → запусти скрипт»), ВНУТРЬ не заглядывают → корректно читают как «план ничего не меняет» и «не доверяю чёрному ящику» → NO-GO. Латать бесполезно.
|
||||
Содержательные правки — ВИДИМЫЕ шаги плана (Edit/Write на каждый файл; судья проверяет: убрано ровно нужное, файл валиден, остальное цело). Особенно КРИТИЧНЫЕ файлы (schema.json валидирует весь реестр — битый JSON роняет загрузку) — прямой Write чистого содержимого, не слепая резка внутри скрипта.
|
||||
Прогон тестов — отдельный видимый шаг, не внутри скрипта-комбайна.
|
||||
Коммит-через-скрипт (§5/§D) — ТОЛЬКО для механики git add/commit/push, НЕ для самих правок и не для верификации. Не расширяй его, чтобы протащить работу мимо стены.
|
||||
Симптом хитрости: план = «Write скрипт + запусти скрипт», реальная работа невидима. Поймал себя — переделай на видимые шаги, не дожимай owner-seal
|
||||
|
||||
[↑ наверх](#top)
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
# Спека: само-пауза под стеной «роутер-наставник»
|
||||
|
||||
## Цель
|
||||
|
||||
Под стеной — и в разговорном режиме, и в режиме исполнения — контроллер должен уметь самостоятельно дождаться вердикта проверки (наставник → судья), не возвращая ход владельцу. Сейчас единственный задокументированный в гайде способ ожидания, инструмент `ScheduleWakeup`, стеной не пропускается: после записи спеки или плана контроллер упирается в блок и вынужден отдавать ход. Это рассинхрон гайда и кода. Цель — закрыть разрыв в коде стены и привести гайд в соответствие с реальным поведением в обоих местах ожидания.
|
||||
|
||||
## Контракт: код стены — допуск само-паузы {#D1}
|
||||
|
||||
- Инструмент `ScheduleWakeup` относится к классу «нулевого эффекта»: он только переносит будущий ход самого контроллера и не изменяет ни репозиторий, ни внешние системы, согласия владельца не требует. По воздействию он эквивалентен «смотрящим»/«запросным» инструментам, которые стена уже пропускает.
|
||||
- Стена обязана пропускать `ScheduleWakeup` во **всех** режимах: разговорном (нет опечатанного плана), деградированном (артефакт отсутствует / не `live-block`) и исполнении (под валидным опечатанным планом).
|
||||
- Допуск `ScheduleWakeup` **не двигает** указатель шагов плана: это ожидание, а не шаг реализации.
|
||||
- Правка строго **аддитивная**. Существующее поведение блокировки мутаторов (Edit/Write/мутирующий Bash вне текущего шага) и все проверки согласия/качества сохраняются без изменений.
|
||||
- Edge: инструмент с похожим «ждущим» поведением, но не входящий в явный список нулевого эффекта, по-прежнему оценивается обычными правилами — «нулевой эффект» не присваивается по умолчанию.
|
||||
|
||||
## Контракт: гайд — правда в обоих местах ожидания {#D2}
|
||||
|
||||
Гайд `docs/superpowers/router-mentor-wall-GUIDE.md` должен описывать ожидание вердикта так, как оно работает на самом деле:
|
||||
|
||||
- **Основной способ** — фоновый запуск `verdict-wait.mjs`: он возвращает управление контроллеру ровно тогда, когда стадия снимка «осела» (ранний возврат, предел 5 мин), и уже допущен стеной во всех режимах.
|
||||
- **Запасной способ** — `ScheduleWakeup` (слепой таймер по времени) — после правки D1 допущен стеной.
|
||||
- Из текста должны быть **убраны или исправлены** все утверждения, что само-пауза под стеной невозможна, и что ожидание печати неизбежно означает возврат хода владельцу. Затронуты как минимум: шапка п.4, блок «Урок 2026-06-19» п.3, и любые упоминания «границы хода» как единственного канала доставки вердикта.
|
||||
- Правка делается **по смыслу** — затронутые места переписываются связно, а не дополняются одной строкой поверх старого утверждения.
|
||||
|
||||
## Критерии приёмки и edge-cases {#D3}
|
||||
|
||||
- Юнит-проверка: `ScheduleWakeup` в разговорном режиме (нет плана) → allow.
|
||||
- Юнит-проверка: `ScheduleWakeup` под валидным `live-block` планом → allow, указатель шага не сдвинут.
|
||||
- Юнит-проверка (анти-регресс): мутирующий инструмент вне текущего шага по-прежнему → block; «смотрящие» по-прежнему → allow.
|
||||
- Полный свод тестов стены — зелёный (subset под стеной недостоверен; зелёность подтверждается полным сводом).
|
||||
- Гайд: не осталось ни одного места, утверждающего недоступность само-паузы; оба способа ожидания (фоновый `verdict-wait`, `ScheduleWakeup`) описаны связно.
|
||||
|
||||
```verified-context-json
|
||||
[
|
||||
{"id":"vc-query-set","kind":"EXTRACTED","ref":"tools/enforce-supreme-gate.mjs","anchor":"const QUERY_ONLY_TOOLS = new Set("},
|
||||
{"id":"vc-isqueryonly","kind":"EXTRACTED","ref":"tools/enforce-supreme-gate.mjs","anchor":"export function isQueryOnly(toolUse)"},
|
||||
{"id":"vc-verdict-wait","kind":"EXTRACTED","ref":"tools/verdict-wait.mjs","anchor":"read-only сторож видимости"}
|
||||
]
|
||||
```
|
||||
@@ -82,7 +82,9 @@ const EPHEMERAL_META_TOOLS = new Set(['TodoWrite']); // меняют
|
||||
// Свободны и в разговорном, и под планом (decideMode). НЕ путать с isObserveOnly (локальный zero-effect):
|
||||
// здесь намеренно входят WebFetch/WebSearch/ToolSearch и read-only браузер. Действующий браузер
|
||||
// (click/type/fill/select) и MCP-запись сюда НЕ входят — они идут через tools-json сеанса.
|
||||
const QUERY_ONLY_TOOLS = new Set(['ToolSearch', 'WebFetch', 'WebSearch']);
|
||||
// ScheduleWakeup (2026-06-20): само-пауза нулевого эффекта — лишь переносит будущий ход контроллера,
|
||||
// ничего не мутирует и согласия не требует → пускается во всех режимах (ждать печать, не отдавая ход).
|
||||
const QUERY_ONLY_TOOLS = new Set(['ToolSearch', 'WebFetch', 'WebSearch', 'ScheduleWakeup']);
|
||||
const READONLY_BROWSER_SUFFIXES = ['browser_navigate', 'browser_snapshot', 'browser_wait_for', 'browser_take_screenshot'];
|
||||
export function isQueryOnly(toolUse) {
|
||||
if (!toolUse || typeof toolUse.name !== 'string') return false;
|
||||
|
||||
@@ -355,6 +355,27 @@ describe('isQueryOnly (B+C: смотрящие инструменты — сво
|
||||
});
|
||||
});
|
||||
|
||||
describe('ScheduleWakeup — само-пауза нулевого эффекта (все режимы, указатель не двигает)', () => {
|
||||
it('isQueryOnly: ScheduleWakeup → true', () => {
|
||||
expect(isQueryOnly({ name: 'ScheduleWakeup' })).toBe(true);
|
||||
});
|
||||
it('разговорный (нет плана): ScheduleWakeup → allow', () => {
|
||||
const r = decideMode({ toolUse: { name: 'ScheduleWakeup', input: {} }, frozenPlan: null, frozenArtifact: null, stepPtr: 0, key: 'k' });
|
||||
expect(r.decision).toBe('allow');
|
||||
expect(r.mode).toBe('conversational');
|
||||
});
|
||||
it('под live-block планом: ScheduleWakeup → allow, указатель не сдвинут', () => {
|
||||
const PLANL = { plan_id: 'x', frozen_at: 1, judge_mode: 'live-block', steps: [{ n: 1, op: 'Write', object: 'tools/foo.mjs' }], sig: 'ok' };
|
||||
const ART = { artifact_id: 'a', judge_mode: 'live-block', sig: 'ok' };
|
||||
const r = decideMode(baseMode({ toolUse: { name: 'ScheduleWakeup', input: {} }, frozenPlan: PLANL, frozenArtifact: ART, stepPtr: 0 }));
|
||||
expect(r.decision).toBe('allow');
|
||||
expect(r.advanceTo).toBeUndefined();
|
||||
});
|
||||
it('анти-регресс: мутатор Write по-прежнему НЕ нулевого эффекта', () => {
|
||||
expect(isQueryOnly({ name: 'Write' })).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('B+C: смотрящие инструменты пускаются в обоих режимах (wiring)', () => {
|
||||
it('разговорный (нет плана): ToolSearch/WebFetch/браузер-смотр → allow', () => {
|
||||
for (const n of ['ToolSearch', 'WebFetch', 'WebSearch', 'mcp__playwright__browser_navigate'])
|
||||
|
||||
Reference in New Issue
Block a user