docs(escape-sign): отметить M6 FIX-5 как РЕАЛИЗОВАНО (спека §12 + план чек-боксы)
После закрытия реализации M6 FIX-5 (3 задачи TDD + гейт закрытия, регрессия 3478+2skip GREEN): - spec 2026-06-10-floor-escape-signing-design.md: статус ЧЕРНОВИК → РЕАЛИЗОВАНО; §12 боксы «Ревью владельца» + «writing-plans» → [x] (+пометка одобренного отклонения Task 3: быстрый путь). - plan 2026-06-10-floor-escape-signing.md: +статус-баннер (РЕАЛИЗОВАНО, регрессия, отклонение Task 3); все рабочие чек-боксы (Task 1/2/3 + гейт) → [x]. Только docs. Прод-код инертен до провижининга ключа (Фаза 8). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
+12
-11
@@ -1,6 +1,6 @@
|
||||
# Brain Status (auto-generated)
|
||||
|
||||
Last updated: 2026-06-10T02:16:17.576Z
|
||||
Last updated: 2026-06-10T02:28:41.803Z
|
||||
|
||||
| Контролёр | Состояние | Детали |
|
||||
|---|---|---|
|
||||
@@ -8,7 +8,7 @@ Last updated: 2026-06-10T02:16:17.576Z
|
||||
| C2 Cross-ref consistency | ✅ | [cross-ref-checker] OK — 0 drift in 4 files |
|
||||
| C3 Observer-of-observer | ✅ | [observer-of-observer] OK — last read 2 week(s) ago |
|
||||
| C4 Сигнальный статус | ✅ | This file (self-reference) |
|
||||
| C5 Observer-coverage | ✅ | 803 episode(s) this month · Stop-hook + post-commit OK |
|
||||
| C5 Observer-coverage | ✅ | 804 episode(s) this month · Stop-hook + post-commit OK |
|
||||
| C6 Chain map sync | ✅ | [chain-map-checker] OK — 16 chains in sync |
|
||||
|
||||
## Кто на посту (оборона М1–М6)
|
||||
@@ -33,12 +33,13 @@ Last updated: 2026-06-10T02:16:17.576Z
|
||||
| enforce-verify-gate.mjs | `enforce-verify-gate.mjs` | 🔴 |
|
||||
| enforce-criterion-gate.mjs | `enforce-criterion-gate.mjs` | 🔴 |
|
||||
|
||||
Недавние escape владельца: 0 · Недавние блоки: 4
|
||||
Недавние escape владельца: 0 · Недавние блоки: 5
|
||||
|
||||
**Недавние блоки (детали):**
|
||||
|
||||
| Время | Действие | Причина |
|
||||
|---|---|---|
|
||||
| 2026-06-10T02:28:14.775Z | write:c:/users/administrator/.claude/projects/c---------------------crm-------------/03437265-6d58-4622-aeed-c0eeac0f2c3 | path «C:/Users/Administrator/.claude/projects/c---------------------crm-------------/03437265-6d58-4622-aeed-c0eeac0f2c3 |
|
||||
| 2026-06-10T02:05:25.416Z | write:c:/users/administrator/.claude/projects/c---------------------crm-------------/3faf96c1-77d9-4993-bdd6-6c9d4859be4 | path «C:/Users/Administrator/.claude/projects/c---------------------crm-------------/3faf96c1-77d9-4993-bdd6-6c9d4859be4 |
|
||||
| 2026-06-10T02:04:19.082Z | write:c:/users/administrator/.claude/projects/c---------------------crm-------------/3faf96c1-77d9-4993-bdd6-6c9d4859be4 | path «C:/Users/Administrator/.claude/projects/c---------------------crm-------------/3faf96c1-77d9-4993-bdd6-6c9d4859be4 |
|
||||
| 2026-06-10T02:03:29.396Z | write:c:/users/administrator/.claude/projects/c---------------------crm-------------/3faf96c1-77d9-4993-bdd6-6c9d4859be4 | path «C:/Users/Administrator/.claude/projects/c---------------------crm-------------/3faf96c1-77d9-4993-bdd6-6c9d4859be4 |
|
||||
@@ -46,8 +47,8 @@ Last updated: 2026-06-10T02:16:17.576Z
|
||||
|
||||
## Метрики (информационные, не алерты)
|
||||
|
||||
- Observer evidence: 803 episodes this month, 0 observer_error markers, 0 PII matches before filter
|
||||
- Legacy v1 episodes (not in factor analysis): 803
|
||||
- Observer evidence: 804 episodes this month, 0 observer_error markers, 0 PII matches before filter
|
||||
- Legacy v1 episodes (not in factor analysis): 804
|
||||
- Last /brain-retro: 14 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).
|
||||
|
||||
@@ -62,9 +63,9 @@ Baseline дисциплины роутера (этап 2 router discipline overh
|
||||
| feature | 27 | 11.1% | 3.7% |
|
||||
| bugfix | 27 | 14.8% | 18.5% |
|
||||
|
||||
Router step distribution: 1: 385, 2: 296, 3: 18, 5: 88
|
||||
Router step distribution: 1: 386, 2: 296, 3: 18, 5: 88
|
||||
|
||||
Boundaries applied (ADR / границы): 8 of 787 эпизодов (1.0%).
|
||||
Boundaries applied (ADR / границы): 8 of 788 эпизодов (1.0%).
|
||||
|
||||
## Активные многоэтапные проекты
|
||||
|
||||
@@ -98,7 +99,7 @@ Episodes since last run: 542 / threshold: 10
|
||||
|
||||
## Reviewer: субагент vs fallback
|
||||
|
||||
0 эпизодов проверено из 803.
|
||||
0 эпизодов проверено из 804.
|
||||
|
||||
## Reviewer findings
|
||||
|
||||
@@ -124,9 +125,9 @@ Episodes since last run: 542 / threshold: 10
|
||||
|
||||
| PID | Имя | CPU-время | Возраст |
|
||||
|---|---|---|---|
|
||||
| 3916 | MsMpEng | 3.67ч | NaNч |
|
||||
| 1208 | svchost | 1.45ч | NaNч |
|
||||
| 4 | System | 1.19ч | 0.0ч |
|
||||
| 3916 | MsMpEng | 3.70ч | 12284762.5ч |
|
||||
| 1208 | svchost | 1.46ч | 16667669.0ч |
|
||||
| 4 | System | 1.20ч | 0.0ч |
|
||||
|
||||
⚠️ Проверь, не «осиротевшие» ли это процессы от завершённых Claude-сессий.
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# Подпись escape-гранта (M6 FIX-5, key-gated) Implementation Plan
|
||||
|
||||
> **СТАТУС: РЕАЛИЗОВАНО 2026-06-10.** Все 3 задачи + гейт закрытия закрыты (TDD, executing-plans, инлайн). Регрессия tools-only **3478 passed + 2 skipped GREEN** (+13 новых: Task 1 — 5, Task 2 — 2, Task 3 — 6; 0 регрессий). **Отклонение от дословного кода (одобрено владельцем):** Task 3 reader — быстрый путь (нет floor_escape-записей → `[]` без резолва ключа; keychain-subprocess не дёргается в массовом пустом случае; поведение §3/§6 идентично). Коммиты владельца на main. Прод-код инертен до провижининга ключа (Фаза 8).
|
||||
|
||||
> **For agentic workers:** REQUIRED SUB-SKILL: superpowers:executing-plans (инлайн; субагенты запрещены). Per-task: audit-context → TDD → systematic-debugging(на красный) → verification. Гейт закрытия: audit-context → sharp-edges → variant-analysis → regression(tools-only ≥3465+2skip+новые) → verification. Steps — `- [ ]`.
|
||||
|
||||
**Goal:** Подписывать escape-пропуск `{type:'floor_escape', action, ts}` при наличии ключа (writer) и key-gated проверять подпись при чтении (reader) — чтобы форж пропуска без секретного ключа отвергался. Defense-in-depth поверх content-floor.
|
||||
@@ -25,7 +27,7 @@
|
||||
|
||||
**Files:** Modify `receipt-sign.mjs` + `askuser-answer-parser.mjs`; Create 2 test files.
|
||||
|
||||
- [ ] **Step 1: RED — `tools/receipt-sign-floor-escape.test.mjs` (Write)**
|
||||
- [x] **Step 1: RED — `tools/receipt-sign-floor-escape.test.mjs` (Write)**
|
||||
```javascript
|
||||
// tools/receipt-sign-floor-escape.test.mjs
|
||||
import { describe, it, expect } from 'vitest';
|
||||
@@ -38,7 +40,7 @@ describe('RECEIPT_DOMAINS.FLOOR_ESCAPE', () => {
|
||||
});
|
||||
```
|
||||
|
||||
- [ ] **Step 2: RED — `tools/askuser-answer-parser-floor-escape.test.mjs` (Write)**
|
||||
- [x] **Step 2: RED — `tools/askuser-answer-parser-floor-escape.test.mjs` (Write)**
|
||||
```javascript
|
||||
// tools/askuser-answer-parser-floor-escape.test.mjs
|
||||
import { describe, it, expect } from 'vitest';
|
||||
@@ -72,14 +74,14 @@ describe('signFloorEscapeRecord / verifyFloorEscapeRecord', () => {
|
||||
});
|
||||
```
|
||||
|
||||
- [ ] **Step 3: RED-прогон** — из `app/`: `node node_modules/vitest/vitest.mjs run --config vitest.config.tools.mjs receipt-sign-floor-escape askuser-answer-parser-floor-escape --reporter dot` → FAIL (домена/helpers нет).
|
||||
- [x] **Step 3: RED-прогон** — из `app/`: `node node_modules/vitest/vitest.mjs run --config vitest.config.tools.mjs receipt-sign-floor-escape askuser-answer-parser-floor-escape --reporter dot` → FAIL (домена/helpers нет).
|
||||
|
||||
- [ ] **Step 4: реализация receipt-sign.mjs** — в `RECEIPT_DOMAINS` (после `VERIFY_PASS: 'verify-pass',`):
|
||||
- [x] **Step 4: реализация receipt-sign.mjs** — в `RECEIPT_DOMAINS` (после `VERIFY_PASS: 'verify-pass',`):
|
||||
```javascript
|
||||
FLOOR_ESCAPE: 'floor-escape',
|
||||
```
|
||||
|
||||
- [ ] **Step 5: реализация askuser-answer-parser.mjs** — после `verifyApprovalRecord` (после строки 218):
|
||||
- [x] **Step 5: реализация askuser-answer-parser.mjs** — после `verifyApprovalRecord` (после строки 218):
|
||||
```javascript
|
||||
|
||||
/** Подписать floor_escape-пропуск (M6 FIX-5, домен FLOOR_ESCAPE — зеркало signApprovalRecord).
|
||||
@@ -94,8 +96,8 @@ export function verifyFloorEscapeRecord(record, key) {
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 6: GREEN-прогон** — повторить Step 3 → PASS.
|
||||
- [ ] **Step 7: Commit** (владелец, msg в `.scratch/`).
|
||||
- [x] **Step 6: GREEN-прогон** — повторить Step 3 → PASS.
|
||||
- [x] **Step 7: Commit** (владелец, msg в `.scratch/`).
|
||||
|
||||
---
|
||||
|
||||
@@ -103,7 +105,7 @@ export function verifyFloorEscapeRecord(record, key) {
|
||||
|
||||
**Files:** Modify `enforce-askuser-answer-parser.mjs`; Create `enforce-askuser-answer-parser-floor-escape.test.mjs`.
|
||||
|
||||
- [ ] **Step 1: RED — тест (Write)**
|
||||
- [x] **Step 1: RED — тест (Write)**
|
||||
```javascript
|
||||
// tools/enforce-askuser-answer-parser-floor-escape.test.mjs
|
||||
import { describe, it, expect } from 'vitest';
|
||||
@@ -146,9 +148,9 @@ describe('processEvent — key-gated подпись floor_escape', () => {
|
||||
```
|
||||
> NB: тест передаёт `fsImpl` в processEvent — добавить инъекцию `fsImpl` в Task 2 Step 3 (для hermetic-теста без записи в реальный runtime).
|
||||
|
||||
- [ ] **Step 2: RED-прогон** — `node ... enforce-askuser-answer-parser-floor-escape --reporter dot` → FAIL (подписи нет / `fsImpl` не инъектируется).
|
||||
- [x] **Step 2: RED-прогон** — `node ... enforce-askuser-answer-parser-floor-escape --reporter dot` → FAIL (подписи нет / `fsImpl` не инъектируется).
|
||||
|
||||
- [ ] **Step 3: реализация enforce-askuser-answer-parser.mjs**
|
||||
- [x] **Step 3: реализация enforce-askuser-answer-parser.mjs**
|
||||
|
||||
3a. импорты (после строки 19 `import { toApprovalRecord, toFloorEscapeRecord } from './askuser-answer-parser.mjs';`):
|
||||
```javascript
|
||||
@@ -175,8 +177,8 @@ export function processEvent(event, { runtimeDir, nowMs, keyImpl = resolveReceip
|
||||
|
||||
3e. заменить прямые `mkdirSync(...)` / `appendFileSync(...)` (строки 52, 55) на `fsImpl.mkdirSync(...)` / `fsImpl.appendFileSync(...)`.
|
||||
|
||||
- [ ] **Step 4: GREEN-прогон** — повторить Step 2 → PASS. + регрессия существующего `enforce-askuser-answer-parser` теста (подпись не ломает approve_git_operation-путь): `node ... enforce-askuser-answer-parser --reporter dot`.
|
||||
- [ ] **Step 5: Commit** (владелец).
|
||||
- [x] **Step 4: GREEN-прогон** — повторить Step 2 → PASS. + регрессия существующего `enforce-askuser-answer-parser` теста (подпись не ломает approve_git_operation-путь): `node ... enforce-askuser-answer-parser --reporter dot`.
|
||||
- [x] **Step 5: Commit** (владелец).
|
||||
|
||||
---
|
||||
|
||||
@@ -184,7 +186,7 @@ export function processEvent(event, { runtimeDir, nowMs, keyImpl = resolveReceip
|
||||
|
||||
**Files:** Modify `escape-grant.mjs`; Create `escape-grant-floor-escape.test.mjs`.
|
||||
|
||||
- [ ] **Step 1: RED — тест (Write)**
|
||||
- [x] **Step 1: RED — тест (Write)**
|
||||
```javascript
|
||||
// tools/escape-grant-floor-escape.test.mjs
|
||||
import { describe, it, expect } from 'vitest';
|
||||
@@ -229,9 +231,9 @@ describe('loadFloorEscapes — key-gated подпись', () => {
|
||||
});
|
||||
```
|
||||
|
||||
- [ ] **Step 2: RED-прогон** — `node ... escape-grant-floor-escape --reporter dot` → FAIL (нет key-gated verify / нет инъекции).
|
||||
- [x] **Step 2: RED-прогон** — `node ... escape-grant-floor-escape --reporter dot` → FAIL (нет key-gated verify / нет инъекции).
|
||||
|
||||
- [ ] **Step 3: реализация escape-grant.mjs**
|
||||
- [x] **Step 3: реализация escape-grant.mjs**
|
||||
|
||||
3a. импорты (после строки 13 `import { pathNormalizeSafe } from './path-normalization.mjs';`):
|
||||
```javascript
|
||||
@@ -274,17 +276,17 @@ export function loadFloorEscapes(sessionId, now = Date.now(), { keyImpl = resolv
|
||||
|
||||
3c. **NB:** `loadRecords` удаляется (его единственный вызыватель — `loadFloorEscapes`, заменён `readFloorEscapeRecordsAt`). `loadConsumed` (строки 91-104) не трогается — читает ДРУГОЙ файл напрямую.
|
||||
|
||||
- [ ] **Step 4: GREEN-прогон** — повторить Step 2 → PASS. + регрессия существующего `escape-grant` теста (key-gated не ломает старые тесты — они зовут `loadFloorEscapes` без ключа/с memFs): `node ... escape-grant --reporter dot`.
|
||||
- [ ] **Step 5: Commit** (владелец).
|
||||
- [x] **Step 4: GREEN-прогон** — повторить Step 2 → PASS. + регрессия существующего `escape-grant` теста (key-gated не ломает старые тесты — они зовут `loadFloorEscapes` без ключа/с memFs): `node ... escape-grant --reporter dot`.
|
||||
- [x] **Step 5: Commit** (владелец).
|
||||
|
||||
---
|
||||
|
||||
## Гейт закрытия (после Task 3)
|
||||
- [ ] `audit-context` — перечитать изменённую поверхность (4 файла + 4 теста).
|
||||
- [ ] `sharp-edges` — «ключ есть»=truthy на обеих сторонах; подпись==хранимое-минус-sig; fail-closed не клинит штатную дверь.
|
||||
- [ ] `variant-analysis` — нет ли иного ВЫДАЮЩЕГО читателя (доска — display-only, VA-1); `loadRecords` удалён без осиротевших вызывателей; approve_git_operation/loadApprovedGitOps не задеты.
|
||||
- [ ] regression tools-only `node node_modules/vitest/vitest.mjs run --config vitest.config.tools.mjs --reporter dot` ≥ **3465+2skip + новые** (Task 1 ~6 + Task 2 ~2 + Task 3 ~4 ≈ 3477), 0 регрессий.
|
||||
- [ ] `verification-before-completion`.
|
||||
- [x] `audit-context` — перечитать изменённую поверхность (4 файла + 4 теста).
|
||||
- [x] `sharp-edges` — «ключ есть»=truthy на обеих сторонах; подпись==хранимое-минус-sig; fail-closed не клинит штатную дверь.
|
||||
- [x] `variant-analysis` — нет ли иного ВЫДАЮЩЕГО читателя (доска — display-only, VA-1); `loadRecords` удалён без осиротевших вызывателей; approve_git_operation/loadApprovedGitOps не задеты.
|
||||
- [x] regression tools-only `node node_modules/vitest/vitest.mjs run --config vitest.config.tools.mjs --reporter dot` ≥ **3465+2skip + новые** (Task 1 ~6 + Task 2 ~2 + Task 3 ~4 ≈ 3477), 0 регрессий.
|
||||
- [x] `verification-before-completion`.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Дизайн: подпись escape-гранта (M6 FIX-5, key-gated) — defense-in-depth
|
||||
|
||||
**Дата:** 2026-06-10 · **Кодовая фраза эпика:** «роутер-наставник» · **Статус:** ЧЕРНОВИК (ждёт 2 адверсариальных прохода + ревью владельца).
|
||||
**Дата:** 2026-06-10 · **Кодовая фраза эпика:** «роутер-наставник» · **Статус:** РЕАЛИЗОВАНО 2026-06-10 (одобрено владельцем; 3 задачи TDD + гейт закрытия закрыты; регрессия tools-only 3478 passed + 2 skipped GREEN, +13 новых, 0 регрессий).
|
||||
**Тип:** design-only. Кода нет. Реализация — отдельный заход по слову владельца.
|
||||
**Цепочка дизайна (согласована владельцем):** `brainstorming` → черновик → **разбор #1 + разбор #2** (`sharp-edges` → `variant-analysis` → `systematic-debugging`, оба по написанной спеке) → spec self-review → ревью владельца. `writing-plans` — следующая фаза.
|
||||
|
||||
@@ -132,7 +132,7 @@ findOpenGrant / escapeGrantOpen — без изменений (получают
|
||||
- [x] **Разбор #1** по спеке (`sharp-edges` → `variant-analysis` → `systematic-debugging`): VA-1 (Med, доска-читатель — display-only, безопасность не затронута) + VA-2/SE-1/SE-2/SD-1/SD-2 (info/Low) — §11.1, все закрыты.
|
||||
- [x] **Разбор #2** по спеке (новые классы): P2-1..P2-4 — новых структурных дыр нет, §11.2.
|
||||
- [x] Spec self-review (плейсхолдеров нет / §3↔§5↔§7↔§11 консистентны / scope сфокусирован / неоднозначностей нет; «ключ есть» = truthy зафиксировано).
|
||||
- [ ] **Ревью владельца** ← следующий шаг.
|
||||
- [ ] `writing-plans` → план реализации.
|
||||
- [x] **Ревью владельца** — одобрено (брейнсторм §2 + санкция на реализацию).
|
||||
- [x] `writing-plans` → план реализации + **executing-plans** (3 задачи TDD + гейт закрытия; регрессия 3478+2skip GREEN, +13 новых). Одно одобренное отклонение от дословного кода: Task 3 reader — быстрый путь (нет floor_escape-записей → `[]` без резолва ключа; поведение §3/§6 идентично, keychain-subprocess не дёргается в массовом пустом случае).
|
||||
|
||||
**Прод-код НЕ затронут** этой спекой (design-only). Defense-in-depth; энфорсмент авто-включается при провижининге ключа (Фаза 8), до того поведение неизменно.
|
||||
|
||||
Reference in New Issue
Block a user