Commit Graph

370 Commits

Author SHA1 Message Date
Дмитрий af3e11b6cd feat(m5): classifyDestructive двухуровневый + rewire a2CaseSelect/detectHighRisk (§4, N1)
Пакет 1 Машины 5 (роутер-наставник, пол). Единый источник разрушительности
classify-destructive.mjs: floor (точный необратимый набор, hard-block) + suspicious
(грубый набор для голосов судьи), инвариант floor => suspicious.

- N1: голый migrate/migrate:rollback/migrate --force => suspicious, НЕ floor (деплой не ломается).
- rewire a2CaseSelect (M4) и detectHighRisk (M3) на classifyDestructive.suspicious;
  оба локальных DESTRUCTIVE_RE удалены (Δ9-б — единственный источник).
- Δ9(б) seed CI-инвариант m5-floor-invariants.test.mjs (positive-control, не вакуумный).
- sharp-edges (Step 1.9): floor force-push выровнен с каноном shell-content — закрыт
  обход кавычками git push "--force" (длинные флаги без обязательного \s; -f/+ с \s).
- parity к двум прежним regex сохранён (format/db:wipe/force-push-литерал).

Регрессия tools-only: 2608 passed + 2 skip (+48). Residuals (chaining/reset-quote)
переданы Пакету 2 (tokenizeBash посегментно).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 11:21:38 +03:00
Дмитрий ae81a52a99 fix(router-mentor): third audit (correctness lens) — close 3 M4 fail-open/crash holes
Третий построчный аудит машин 1-4 свежим объективом (корректность логики /
реальные баги — НЕ понимание, НЕ грабли; это были два прошлых прохода).
4 читающих под-агента code-analyzer. M1/M2/M3 — багов ядра нет (подтверждено).
M4 (судья, инертен; код должен быть верен и при включении): 3 реальные дыры по TDD.

M4:
- judge-engine.mjs runJudge: (raw.objections||[]).filter((o)=>o.verdict) падал на
  objections=[null] (o.verdict на null) и на не-массиве (.filter is not a function).
  || гасит только falsy. Краш ломал вердикт; в инертной обёртке выброс уходил в
  catch→block:false = fail-open. Fix: Array.isArray(...)?...:[] + (o && o.verdict).
- judge-verdict-slots.mjs: String(raw).trim().length скрывал не-строки — слот {}
  давал '[object Object]' (длина 15) и проходил как содержательный (мусорный
  объект/массив штамповал форму вердикта). Fix: слот обязан быть строкой
  (typeof raw !== 'string' → trivial). Мягкий fail-open формы закрыт.
- judge-orchestrator.mjs runGateLadder: step.run() без try/catch пробрасывал
  исключение упавшего шага пола вместо «пол не пройден» → решение неопределённо
  (в обёртке catch→block:false = fail-open). Fix: бросок шага = passed:false
  (fail-closed → блок), последующие не запускаются. Чистый модуль теперь сам
  гарантирует безопасную сторону, не полагаясь на обёртку.

Регрессия tools-only 2560 passed + 2 skip (+5 TDD-тестов, 0 регрессий).

Осознанно НЕ менялось (без призраков):
- M1 verifyChain без 3-го арг = нарушение контракта вызова, не валидный вход.
- M2 node-в-цепочке = то же разрешение, что одиночный node (контракт, тест L53);
  readonly-git-в-цепочке блок = осознанный default-deny (fail-safe).
- M3 defer уже защищён G-фиксом (if e.status!=='pending' return e — ДО defer);
  N3 stale-комментарий (код строже докстринга).
- M4-C DESTRUCTIVE_RE иллюстративен (divergence всё равно судится; разрушительный
  bash режется полом M2/M5 до судьи); M4-D slop-counter↔logVerdict — live-wiring.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 08:11:12 +03:00
Дмитрий c4f63e36b5 fix(router-mentor): sharp-edges audit M1-M4 — close 8 misuse-resistance holes
Второй аудит машин 1-4 другим объективом (sharp-edges: устойчивость к
неправильному применению / мягкие умолчания / совпадение по пустоте-подстроке).
Криптоядра здоровы (подтверждено). 8 реальных дыр закрыты по TDD:

M3:
- coverage-machine F-1: покрытие считалось по двусторонней ПОДСТРОКЕ — produces
  "a" покрывал запрос "audit-rls-policy" (ложное «всё покрыто»). Новый tokensCover:
  точное равенство ИЛИ подмножество слов по границам. coveringSkill + coverageRegistry.
- router-engine F-8: confidence не проверялся на диапазон — 5/Infinity проходили как
  «уверен» (обход воздержания 5.2), -3 как принуд. abstain. validateTrace: [0,1] finite.
- round-control C: пустой roundKey="" активировал managed-режим (!= null) → все сессии
  делили один счётчик-бакет. Теперь managed требует непустую строку.
- router-learning-queue G: повторное approve уже-решённого id повторно клало запись в
  фонд (дубль). applyApprovalBatch: переводит только status==='pending'.

M2:
- plan-lock F5: шаг с пустым object был джокером (object:'' матчил действие, чей путь
  не извлёкся → object''). actionMatchesStep: пустой object шага не матчит ничего.

M4 (инертна; чистые fail-closed правки кода, корректны и при включении):
- judge-slop-counter H: битый/null вердикт в списке ронял счёт (v.missing на null).
  Теперь не крашит, считается халтурой (безопасная сторона).
- judge-engine J: consensusDecision на пустом/битом списке дрейфовал к GO. Теперь GO
  только если есть голоса И каждый чистый GO; иначе NO-GO (fail-closed для hard-risk).
- judge-orchestrator K: finalGate снимал вето пола на любой falsy floorBlocked
  (undefined от упавшей проверки = fail-open). Теперь снять может только явный false.

Регрессия tools-only 2555 passed + 2 skip (+15 TDD-тестов, 0 регрессий).

Осознанно НЕ менялось (без призраков):
- M1 receipt-sign domain default '' / разделитель пробел — backward-compat контракт
  (тест 18-19), инъективен на enum-доменах без пробелов.
- M1 action-journal атомарность записи головы + битая .jsonl строка — fail-closed
  (битьё → verifyChain ok:false → стена блокирует); чистого behavioral-теста нет.
- M3 round-control requiredSkills=[] — контракт вызывающего (пустой = не требуется).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 06:24:21 +03:00
Дмитрий c13a1a56a1 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
Дмитрий ded7525be7 fix(m1-foundation): verifyChain fail-closed на битой записи + sessionId path-guard
Аудит Машины 1 (audit-context-building), 2 находки low/defense-in-depth:
N2 — verifyChain больше не бросает TypeError на структурно-битой записи
(null / не-объект / массив, приходит из порченого .jsonl через loadJournal):
guard !e||typeof!=='object'||Array → {ok:false, brokenAt:null}.
N3 — paths() валидирует sessionId (/^[A-Za-z0-9_-]+/) до склейки пути
журнала → throw на ../ / \ . : закрывает path-traversal (fail-closed,
supreme-gate ловит внешним try/catch → block).

N1 (keytar getPasswordSync inert) и N4 (verifyChain/анти-откат — контракт M4)
не трогались: N1 — верное зеркало judge-key-config/llm-judge-config (env —
рабочий путь, fail-closed цел); N4 — deferred межмашинный дизайн.

TDD RED→GREEN, +7 тестов. Регрессия tools-only 2530 passed + 2 skip, 0 регрессий.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 05:03:08 +03:00
Дмитрий 1739b1de08 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
Дмитрий a29f8bdc10 feat(m2): export READING_CMDS as single source of true readers (F-A prep) 2026-06-07 04:32:56 +03:00
Дмитрий 157a52efae fix(m3): learning-queue — reject > approve при конфликте id (hard-rule без явного да НИКАК)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 04:00:06 +03:00
Дмитрий a6b61f5a62 fix(m3): skill-contract — neutrality сканирует все строковые поля inherent+skill (аудит F4)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 03:56:16 +03:00
Дмитрий 6525e44173 fix(m3): coverage-machine — пустой токен не покрывает запрос (аудит F3)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 03:56:10 +03:00
Дмитрий 3446f9e5dc fix(m3): round-control — managed-терминатор по roundKey, авто-инкремент круга (аудит F2)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 03:56:03 +03:00
Дмитрий 1e06b8ddfe fix(m3): router-engine — chosen обязан быть среди candidates (аудит F1)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 03:55:52 +03:00
Дмитрий e423cd70a1 fix(m4): audit closures — goal anchor + card guard + gate-1 coverage gate + sealed criteria + A2 router/packaging + reversibility doubt-blocks 2026-06-07 03:15:56 +03:00
Дмитрий 2683d22d5e feat(m4): judge — discipline floor + seal channel + gate floor + engine + orchestration + postfactum evaluator + inert hook wrapper 2026-06-06 03:07:38 +03:00
Дмитрий 7ee388a061 fix(m3): закрытие находок аудита — гард R4 + терминатор + footguns; F2/F3 как честный остаток 2026-06-05 17:32:45 +03:00
Дмитрий 11024823c4 feat(m3): граф зависимостей решений (#2) + дисциплина доменного навыка (#3) 2026-06-05 17:10:21 +03:00
Дмитрий ed720d11e4 feat(m3): разговорная фаза 2026-06-05 — вход роутера + контроль + выходная верность + честные контракты 2026-06-05 14:52:45 +03:00
Дмитрий e362fd24a6 fix(m2): указатель шага подписан (HMAC step-ptr) — подмена ptr → сброс (R-19) 2026-06-05 06:23:35 +03:00
Дмитрий 527acd7cf3 fix(brain): доменное разделение подписи — план/артефакт/журнал/расписка не взаимозаменяемы (R-31/J6) 2026-06-05 06:21:19 +03:00
Дмитрий 109e35fbc8 fix(m2): session_id из stdin-события, не из env — сессии больше не слипаются (R-28/J3) 2026-06-05 06:09:45 +03:00
Дмитрий d138bd5f0e fix(m2): указатель шага привязан к plan_id — перепечать сбрасывает указатель (R-27/J2) 2026-06-05 04:21:05 +03:00
Дмитрий 86b48a10ef fix(m2): decide самодостаточно проверяет печать артефакта (защита-в-глубину) (F2) 2026-06-05 04:05:22 +03:00
Дмитрий ee7e483e29 fix(m2): actionOf — поля объекта выровнены с B4 (ловит MCP filename/uri/destination) (F1) 2026-06-05 04:04:09 +03:00
Дмитрий 27a7cc9a18 fix(m1): extractPath — расширены path-поля (ловит MCP filename/uri/destination) (B4) 2026-06-05 03:42:40 +03:00
Дмитрий 558f0a4253 fix(m1): seq+ts входят в chain_hash журнала — подмена метаданных ломает цепь (B2) 2026-06-05 03:41:38 +03:00
Дмитрий 317682b59c feat(m3-d): контракты + look-ahead в промпт роутера + проброс runRouter (фикс-2) 2026-06-05 03:24:49 +03:00
Дмитрий 929ad55f2c feat(m3-d): нюх 5.3 + интервьюер 4.4 в промпт роутера (фикс-3) 2026-06-05 03:23:11 +03:00
Дмитрий cb01a482d0 feat(m3-a): checkContractNeutrality — G1 страж нейтральности этикетки (фикс-5, опц.) 2026-06-05 03:22:07 +03:00
Дмитрий 688ff61da2 feat(m3-a): dispatchContract — G3 детерминированная диспетчеризация точно|мягко (фикс-4) 2026-06-05 03:20:55 +03:00
Дмитрий 0c07530195 fix(m3-b): resolveNode заземляет skill-ref по префиксу (superpowers:X -> #19) — фикс-1 2026-06-05 03:18:26 +03:00
Дмитрий 63fb924493 test(m3-e): learning hard-rule invariants + plan — Машина 3 собрана
Машина 3-E «Очередь одобрений + ручка разведки» собрана (TDD): router-learning-queue.mjs
(propose-only + owner batch approval + render/signal/persist; hard-rule «без да — никак»)
+ router-exploration.mjs (ручка %разведки=0 default, проба=вопрос владельцу, риск-гард).
19 новых тестов. Финальная регрессия tools-only 2212 GREEN.

МАШИНА 3 (Роутер-наставник) собрана целиком: 3-A контракты / 3-B граф узлов /
3-C машина охвата / 3-D движок роутера / 3-E очередь обучения. Доставка в живую
инфру (STATUS/brain-retro), K4-поправка, live-wiring, перенос волн — follow-up
после Машины 4 (журнал вопросов).
2026-06-04 19:51:45 +03:00
Дмитрий 15d71658f6 feat(m3-e): exploration knob (#3) — probe = owner question, off by default + risk-guard 2026-06-04 19:50:31 +03:00
Дмитрий 34bfaa9fb9 feat(m3-e): learning queue — propose-only + owner batch approval + render/signal/persist (hard-rule no auto-fill) 2026-06-04 19:49:32 +03:00
Дмитрий da4831a3b6 test(m3-d): router-engine invariants on real graph + plan + questions log
Машина 3-D «Движок роутера» собрана (TDD): router-engine.mjs (detectHighRisk 6.1
детерминированный / validateLevelSkip 6.2 / cheaperOf / validateTrace 5.1 /
groundTrace ОВ-Д2 / buildRouterPrompt+parse+runRouter, llmCall мокается как
router-classifier) + step-pointer.mjs (дерево-указатель волн D6/OQ1, стендово).
35 новых тестов, регрессия tools-only 2193 GREEN. K4-поправка к стене + live-wiring
+ перенос волн в живой main — ОТЛОЖЕНО до Машины 4 (журнал вопросов).
2026-06-04 19:46:09 +03:00
Дмитрий 3b39f624cc feat(m3-d): step-pointer tree (waves D6/OQ1) — standalone, not yet wired into M2 2026-06-04 19:45:04 +03:00
Дмитрий 22f144522d feat(m3-d): router-engine — risk(6.1)/skip(6.2)/price + trace 5.1 + grounding(ОВ-Д2) + buildRouterPrompt/parse/runRouter (llmCall injected, mocked) 2026-06-04 19:43:57 +03:00
Дмитрий 404a938256 test(m3-c): coverage-machine invariants on 3-A contracts + plan
Машина 3-C «Машина охвата A/B/C/D» собрана (TDD): coverage-machine.mjs —
A граф зависимостей (buildDependencyGraph/topoOrder/findHoles/decompositionGroups),
B реестр нужды↔решения (coverageRegistry: дыры+сироты), C requestsChecklist,
D ограничения как нужды (effectiveNeeds), хребет readinessChecklist (4 галочки + §).
Независимый верификатор охвата (рычаг E §6.3). 19 новых тестов, регрессия 2158 GREEN.
2026-06-04 19:26:21 +03:00
Дмитрий 32a19f3a08 feat(m3-c): coverage-machine A/B/C/D + readinessChecklist (C-14, set/graph ops) 2026-06-04 19:23:02 +03:00
Дмитрий 62030e23a7 test(m3-b): node-graph invariants on real registry + plan
Машина 3-B «Граф узлов из реестра» собрана (TDD): node-graph.mjs поверх
loadRegistry — buildNodeGraph/resolveNode (ОВ-Д2 заземление) + twinsOf
(subcategory) / hintLinksOf (chains) / conflictsOf (явные) + checkGraphFreshness
(3.6). 20 новых тестов, регрессия tools-only 2139 GREEN.
2026-06-04 19:19:00 +03:00
Дмитрий 06ac8b80dc feat(m3-b): node-graph from registry — buildNodeGraph/resolveNode (ОВ-Д2) + twins/hints/conflicts + freshness 3.6 2026-06-04 19:17:50 +03:00
Дмитрий 6e3de1aca6 test(m3-a): contract fixtures (own+external) + 3-A invariants + plan + questions log
Машина 3-A «Контракты скилов» собрана (TDD): skill-contract.mjs (схема C-13/L
+ form validator + normalize/accessors + G4 drift-guard) + skill-contract-registry.mjs
(buildRegistry/loadRegistry). 28 новых тестов, регрессия tools-only 2119 GREEN.
Образцы own (writing-plans) + external (operations:process-doc). Журнал вопросов заведён.
2026-06-04 19:12:47 +03:00
Дмитрий 99b82699be feat(m3-a): skill-contract-registry — buildRegistry (validate/dedupe/drift) + loadRegistry (disk) 2026-06-04 19:11:28 +03:00
Дмитрий 901a65237f feat(m3-a): skill-contract schema + form validator + normalize/accessors + G4 drift-guard (C-13/L) 2026-06-04 19:10:24 +03:00
Дмитрий 18a18cfa08 test(m2): supreme-wall invariants — default-deny/seal/seed/step-match (Task 9)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 16:49:29 +03:00
Дмитрий a982580e43 feat(m2): door-coverage — auditDoors (forgotten-channel) + auditExempt (green-pass safety) (Tasks 7,14)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 16:49:10 +03:00
Дмитрий 8642fe85ea 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
Дмитрий 3772eaf756 feat(m2): plan-lock — freeze/verify/match/persist/reconcile/2nd-seal/closed-door (Tasks 1-3,8,11,12)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 16:48:30 +03:00
Дмитрий 4ee84f8fb8 test(m1): foundation cross-invariants (journal tamper / unsigned receipt / runtime deny) 2026-06-04 04:05:10 +03:00
Дмитрий c22ed0b767 feat(m1): runtime-write-deny — block any path-bearing tool (P10-a all channels) 2026-06-04 04:04:25 +03:00
Дмитрий df23a7a6f8 feat(m1): pathNormalize NFC normalization (P10-b unicode evasion) 2026-06-04 04:01:17 +03:00