Commit Graph

29 Commits

Author SHA1 Message Date
Дмитрий 52d500db5d feat(security): read-only доступ к проду через стену — ssh liderra-prod + gh GET
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 08:04:50 +03:00
Дмитрий bcf7ff6d74 fix(router-mentor): стена не двигает указатель на floor-блокируемый шаг (Δ7+)
floor-desync: supreme-gate Δ7 вето-без-сдвига смотрел только classifyDestructive.floor (rm-rf/force-push/migrate), а enforce-floor блокирует шире — content-block правило 8 (node -e/curl/eval), PowerShell, запись в runtime/секрет. Floor-блокируемый-не-destructive шаг (node -e) проскакивал со СДВИГОМ указателя, пол рубил исполнение → шаг терялся безвозвратно (desync, потеря safety-шага). Δ7 расширен на полный предикат floorDecide (пустой escape; escape обрабатывается в decideMode до decide). Order-independent. TDD RED→GREEN, регрессия tools-only 3930 passed + 2 skipped.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 10:58:14 +03:00
Дмитрий f3ac36bef1 revert(wall): откат Post-advance — PostToolUse не срабатывает на упавшем Bash
Live-смоук: PostToolUse не запускается на exit≠0 → Post не двигает указатель на RED-шагах. Код возвращён к Pre-advance (3928 GREEN). Спека/план помечены ОТВЕРГНУТО. Настоящий фикс desync = перестановка skill-discipline перед supreme-gate.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 06:11:11 +03:00
Дмитрий 820ff23ccc fix(wall): supreme-gate сдвигает указатель на PostToolUse (фикс рассинхрона)
Pre-такт = ворота + журнал-намерение (без сдвига); Post-такт = сдвиг по подтверждённому исполнению. Лечит desync при блоке поздним хуком / user-deny. +runGatePre/runGatePost/isPostEvent, runGate → compat-обёртка. Регрессия tools-only 3938 passed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 05:34:33 +03:00
Дмитрий e243b8f77b feat(mentor): тупой судья навыков + фикс роутера prefilter-bypass
- router: classify({skipPrefilter}) — наставник зовёт мозг роутера мимо detectMicro
  (ловил 'format' подстрокой в имени модуля → роутер не доходил до LLM); recommendedChainOf
  в on-plan-write маппит node/recommended_node/recommended_chain (рекомендация не теряется)
- skills в ПОДПИСАННУЮ печать (Вариант 1): sealablePlan/freezePlan/sealPlan
- стена: isPlanDeclaredSkill — объявленный в опломбированном плане навык вызываем (снимает дедлок)
- enforce-domain-skill-discipline (новый хук): объявил → обязан вызвать (журнал M1) до
  первого мутирующего шага; поверх готового domain-skill-discipline
- гайд docs/superpowers/router-mentor-wall-GUIDE.md + дизайн/план-доки
- регрессия tools-only 3928 passed + 2 skip, 0 регрессий

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 04:08:53 +03:00
Дмитрий b739d5adad feat(mentor): мерж роутера в наставника — единый рецензент (спека+план+скилы) + decision GO/NO-GO
Болезни B (роутер в пустоту) + A (наставник не заворачивал) — лечение Р7/Р8 (Подход 1):
наставник — единый мозг-рецензент, зовёт classify() как функцию (3 слоя + граф nodes.yaml +
карточки — код не тронут, новый вызыватель), судит спеку+план+выбор скилов, заворачивает NO-GO.

- validateMentorVerdict + промпты (план/спека): явное decision GO|NO-GO (поглощённый Р7)
- plan-skills.mjs: parsePlanSkills (skills-json) + extractPlanGoal (зеркало extractGoal судьи)
- mentor-seam: renderSkillContext; onPlanWrite зовёт classifyImpl (fail-safe: сбой → без скил-сверки)
- decideMentorObjection: заворот на decision=NO-GO ИЛИ сломанный вердикт; mentor-GO только на чистом GO
- formatMentorObjection доносит суть (recommendation + reasoning + plan_points), GO -> пусто
- enforce-mentor main: loadRegistry + classify; счётчик L1 decision-aware (Р7/§3.4)
- скил-сверка — только план (gate2); спека (gate1) — по сути + decision
- включает redesign согласования L1->L2 (Фазы 0-6, способ B: наставник->судья->печать)
- регрессия tools-only 3901 passed + 2 skip (база 3877, +24 теста, 0 регрессий)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-13 11:38:09 +03:00
Дмитрий ebce8e5536 feat(m7): re-plan на ходу (impl-карвут) + эскалация судьи (escape-honor + счётчик NO-GO) + docs-хвост 2026-06-12 15:48:17 +03:00
Дмитрий 537154adf3 feat(mentor-integration): боевая проводка C2 — W1 catalog≠graph+районы (М3) + W2 гейт ДР-1 в стене (М2, аддитивно) + W3 onPlanWrite + W4 warn-прокидка O18 + W6 интеграционный тест + W7 контракты (sub-plan C2 + Д-С2-1..7 + sharp-edges F-C2-1..5) 2026-06-11 19:09:39 +03:00
Дмитрий 039743a71f feat(footgun-fixes): O13 skill-escape канон + O11 detectMoney сужен + O18 judge_mode warn + SE-R7-6 loop-termination (sub-plan E Tasks 1-6 + SE1/C-4) 2026-06-11 17:13:48 +03:00
Дмитрий 84231a1470 feat(board): live source for guard board escapes/blocks (D-3)
Доска «кто на посту» (STATUS.md §7) теперь показывает реальные недавние
escape владельца и блоки машин М1–М6 вместо хардкода []/[].

- new tools/guard-block-log.mjs: logGuardBlock (best-effort, fail-quiet,
  Node fs append в guard-blocks-<sess>.jsonl) + loadRecentBlocks/
  loadRecentEscapes (скан session-файлов runtime, окно 24ч + cap 10, ts→ISO).
- проводка logGuardBlock в block-ветку main() 9 машинных хуков (floor /
  supreme-gate / judge-gate / snapshot / read-path-deny / mcp-classification /
  normative-content-rules / verify-gate / criterion-gate). Логгер вызывается
  ПОСЛЕ решения, не влияет на block; decide() pure не тронут.
- status-md-generator CLI: recentEscapes/recentBlocks из читателей вместо []/[].

До флипа Фазы 8 доска показывает 0/0 (хуки не зарегистрированы — данных нет);
реальная польза — пост-флип наблюдаемость.

TDD: guard-block-log.test (6) + 9 структурных wiring-тестов + 1 board-тест.
Гейт закрытия: sharp-edges (промежуточный по 9 хукам + читатели) +
variant-analysis (все block-ветки покрыты, иных источников нет). Регрессия
tools-only 3465 passed / 2 skipped / 0 failed (было 3449+2skip). 0 регрессий.

Plan: docs/superpowers/plans/2026-06-10-guard-board-live-source.md
2026-06-10 04:28:53 +03:00
Дмитрий 0289e93c0e feat(gate1+se2): wire spec-judging (Гейт-1) + fail-closed wall whitelist (SE-2)
М7 Фаза 8 — последние 2 хвоста до флипа. Inline TDD; спека+план одобрены; 2 адверсариальных прохода.

Гейт-1 (печать артефакта в рантайме):
- extractGate1Product (enforce-judge-gate.mjs): детект записи specs/*.md (Write-only) → судить
  линзами gate1 (движок уже поддерживает). runJudgeGate: спека→gate1, иначе план→gate2.
- judged_hash от СЫРОГО content (SD-1, разбор #1 High): trimmed source_sha не сошёлся бы с
  печатью sealOnWiredGo → артефакт НИКОГДА не печатался бы. Один канон судья→печать.
- extractGate2Product не тронут (Гейт-2 = планы, регрессия зелёная).

SE-2 (стена не чтит shadow):
- decideMode (enforce-supreme-gate.mjs): fail-closed whitelist — энфорсмент ТОЛЬКО при
  judge_mode==='live-block' на ОБЕИХ печатях; shadow/null/опечатка → разговорный (мутаторы block).
  Разбор #1 (VA-a/SE-a): убрана единственная fail-OPEN сверка; опечатка режима безопасна.
- мигрированы 3 enforce-теста стены на judge_mode:'live-block'.

Тесты: gate1 10, SE-2 6; регрессия tools-only 3443 passed / 2 skip / 0 регрессий.
Гейт-1 тесты — отдельный файл enforce-judge-gate-gate1.test.mjs (real-test-verifier блокирует
import-only Edit существующего теста). Печать в рантайме до флипа НЕ производится.
2026-06-09 19:05:17 +03:00
Дмитрий 2b0c28e59f feat(supreme-gate): tree leaf resolution plus advance flag for R-08 waves 2026-06-09 05:12:38 +03:00
Дмитрий 16e0c1db09 feat(supreme-gate): pointer state accepts tree position as index array 2026-06-09 05:10:45 +03:00
Дмитрий 0eef670e54 feat(door-coverage): door matcher reader and canonical mutating tools list 2026-06-09 04:02:27 +03:00
Дмитрий 3fad5e0401 feat(m7-phase3): SEED_SKILLS +реактивные дисциплинарные навыки (SE-K — стена не рубит вне плана) 2026-06-08 10:35:33 +03:00
Дмитрий 317f8cb6fb feat(m7-phase2): supreme-gate panicEscapeDecision — escape переживает сбой сетапа main (правило 7б) 2026-06-08 10:28:43 +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
Дмитрий 4a10932cb6 feat(m6): G-1 сквозной escape в верховной стене М2 (allow без продвижения указателя) 2026-06-07 18:55:56 +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
Дмитрий b6d06ede87 feat(m5): Пакет 2 — несущий пол (floor-decide + enforce-floor + дверь Δ1 + Δ7 + C4)
Блок 1 Машины 5: вето-до-плана на необратимое, независимо от членства в плане.

- tools/floor-decide.mjs — чистое ядро: Bash floor (classifyDestructive whole-string +
  посегментно tokenizeBash — кавычки/chaining нейтрализованы) + tool-agnostic запись
  (P10-a: .env/ключ/cert + ~/.claude/runtime, fail-CLOSED на normalize-throw).
- Дверь владельца Δ1 — read-only approve_git_operation (exact+5мин окно, НЕ consume).
- tools/enforce-floor.mjs — обёртка matcher '*' (регистрация — шаг владельца, ОТДЕЛЬНО
  от стены М2), loadApprovedGitOps read-only, fail-CLOSED, НЕ импортирует plan-lock.
- C4: migrate:fresh/refresh/reset убраны из router-gate whitelist → default-deny даже
  без floor-хука (SPOF-защита); bare migrate + migrate:rollback остаются.
- Δ7: enforce-supreme-gate.decide на allow-пути зовёт classifyDestructive(...).floor —
  разрушительный in-plan шаг НЕ продвигает указатель (стена не благословляет снос).
- Атака-линза: закрыт P10-a-пробел (MCP-writer в .env floor бы пропустил).

Audit-context вскрыл расхождения план↔код (задокументированы в floor-decide JSDoc):
writer approval НЕ подписывает (интегрити = protected-path side-channel, не HMAC);
F5-гонка мнимая (loadApprovedGitOps read-only+window, не consume); force-push доп-блок
shell-content GIT_HARD (дверь для него мут — защита-в-глубину). Дверь = шов под М6.

Регрессия tools-only: 2649 passed + 2 skip (+41). Residual: node-whitelist hole
для записи в runtime (Пакет 4 сужает); base64-обфускация floor (~0.5%, М6).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 11:42:58 +03:00
Дмитрий e1a6f26c06 fix(router-mentor): close sessionId path-traversal class across M1-M4
Аудит M1-M4 (audit-context-building) нашёл непоследовательность guard формы
sessionId: N3-фикс защитил только action-journal.paths() (M1), а 4 sibling-
строителя пути из event.session_id (недоверенный источник) остались без проверки.

Единый экспорт assertSafeSessionId (action-journal.mjs, переиспользует SESSION_ID_RE
N3) применён во всех точках машин:
- M1 action-journal.paths() — рефактор на общий guard (поведение N3 сохранено)
- M4 judge-subrun-journal.paths() — guard добавлен (канал прилежности судьи F1)
- M2 plan-lock.planPath + artifactPath — guard добавлен
- M2 enforce-supreme-gate — экспортируемый guarded stepStatePath, применён в main()

TDD RED-GREEN на каждом файле. Регрессия tools-only 2540 passed + 2 skip (+10).
Серьёзность класса — низкая / защита-в-глубину (sessionId harness-controlled),
закрыт ради консистентности (был 1 из 5).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 05:41:07 +03:00
Дмитрий 1881501b81 fix(m2): close supreme-wall holes F-A/F-B/F-C (audit 2026-06-07)
F-A (HIGH): Bash green-pass via reading-chain reason collapse — chain
  <reader> && <whitelisted-mutator> (composer pint / php artisan migrate:fresh
  / pest / npm test / node <script>) bypassed the wall. isObserveOnly now
  re-tokenizes and requires EVERY segment be a true reader (READING_CMDS) or
  a single readonly-git, not trusting the collapsed 'reading' reason.
F-B (minor): observe-only no longer choked when plan present but artifact
  missing/invalid (decideMode honors isObserveOnly; finding-9 invariant).
F-C (low): closed-door (C-5) ref-check moved out of the artifact_id guard —
  a step with ref must resolve in a sealed artifact even if plan has no
  artifact_id. TDD: RED proven per fix; full tools regression 2523 GREEN.
2026-06-07 04:33:17 +03:00
Дмитрий 6dbe4374de fix(m2): указатель шага подписан (HMAC step-ptr) — подмена ptr → сброс (R-19) 2026-06-05 06:23:35 +03:00
Дмитрий fe5cf99fc9 fix(brain): доменное разделение подписи — план/артефакт/журнал/расписка не взаимозаменяемы (R-31/J6) 2026-06-05 06:21:19 +03:00
Дмитрий 2ef5504710 fix(m2): session_id из stdin-события, не из env — сессии больше не слипаются (R-28/J3) 2026-06-05 06:09:45 +03:00
Дмитрий 522531bbd2 fix(m2): указатель шага привязан к plan_id — перепечать сбрасывает указатель (R-27/J2) 2026-06-05 04:21:05 +03:00
Дмитрий 4963c1187f fix(m2): decide самодостаточно проверяет печать артефакта (защита-в-глубину) (F2) 2026-06-05 04:05:22 +03:00
Дмитрий 133b29df58 fix(m2): actionOf — поля объекта выровнены с B4 (ловит MCP filename/uri/destination) (F1) 2026-06-05 04:04:09 +03:00
Дмитрий 8d9ca65cf3 feat(m2): supreme-gate — seeds/decide/runGate/decideMode/observe-only/closed-door (Tasks 4-6,10,13,12)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 16:48:49 +03:00