Commit Graph

554 Commits

Author SHA1 Message Date
Дмитрий bffca85399 docs+fix: канон схемы догнал миграции — 39 таблиц описаны, сверка считает обе стороны
Канон знал 82 таблицы и 995 столбцов, а база — 121 и 1470: не описаны были
рекламный модуль, телеграм-рассылки и весь отдел продаж.

Главное, что выяснилось по дороге: db/schema.sql не документ, а исполняемый
файл — миграция 0001_01_01_000000_load_initial_schema заливает его целиком
первым шагом сборки. Перенести туда DDL модулей нельзя: те же таблицы создают
дельта-миграции, их 77 и 49 из них без стражей. Сборка с нуля падала дважды.
Поэтому канон разбит на два файла: schema.sql исполняется, новый
schema_modules.sql только описывает.

Проверено не глазами:
- сборка с нуля 148 из 148 DONE;
- столбцы 1470 против 1470, ноль расхождений по имени, типу, длине и NULL;
- все четыре счётчика расхождений инструмента — ноль;
- schema.sql отдельно исполняется без единой ошибки, ограничения 495=495,
  политики 64=64;
- статанализ 0.

Инструмент сверки усилен: считал только одну сторону и потому не видел
переименования jivo_chat_id в chat_id — старое имя жило в каноне месяц.
Теперь обе стороны, канон из нескольких файлов, понимание RENAME/DROP COLUMN
и DROP TABLE. Починен разбор переносов строки внутри определения столбца.

Сторож SchemaDeltaTest дополнен: файл модулей обязан быть на месте и описывать
39 таблиц, а тело schema.sql их не содержать. Принят вырезанием.

Найдено и НЕ исправлено, нужно решение владельца: задвоенный указатель на
deals и пять политик без NULLIF в миграциях. Оба помечены в тексте канона.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-02 12:53:45 +03:00
Дмитрий 929bf9f45b fix интерфейс: время везде показывается по Москве, а не по часам браузера
Считать портал уже научился по московским суткам. Показывал он вразнобой:
часть страниц просила браузер явно про Москву, двадцать мест оставляли пояс
на его усмотрение. Человек за пределами Москвы видел у заявки не тот день,
что в отчёте, — при том что фильтры и отчёты считают московские сутки.

Двадцать мест поправлены: заявки, счета, проводки, сессии и смена пароля,
происшествия, запросы субъектов ПДн, ступени цен, интеграция с поставщиком,
проекты поставщика, система, посетители, вход под клиентом, кампании,
поле автоподбора, СМС и прогрев у отдела продаж, карточка клиента.

Одно место оставлено гринвичским НАМЕРЕННО и с объяснением рядом:
firstLeadDate собирает дату из уже московских чисел через Date.UTC, и
повторный перевод сдвинул бы день назад.

Сторож tools/storozh-moskovskogo-vremeni.mjs держит правило дальше: любая
печать времени обязана НАЗВАТЬ пояс. Он отличает время от денег - тот же
вызов toLocaleString печатает и суммы, им пояс не нужен. Приёмка вырезанием
в обе стороны: до правки сторож нашёл ровно 20 мест, после - ноль при 303
проверенных файлах; на пустой папке честно говорит "датчик сломан", а не "чисто".
Своих проверок у сторожа десять, написаны до него.

Прогон интерфейса: 232 файла проверок, 1743 зелёных, 0 падений.
Проверка типов и разметка: 7 замечаний, все были ДО правки и не в моих файлах
(проверено прятанием своих правок и повторным прогоном).

Заодно выметен мусор в корне: файлы с именами 1', 140, 2771, 3042, 3404,
out.txt и app/toArray-скобки - обрывки чужих незакавыченных перенаправлений.

Заодно убрана мёртвая функция dirLabel в экране автоподбора: её никто не звал,
она была там до этой правки, и линтер из-за неё не пропускал весь файл.
Решение владельца. Прогон экрана: 15 файлов проверок, 84 зелёных.
2026-08-02 11:09:51 +03:00
Дмитрий 38cafbf94a chore: сторож чистоты тестовой базы — называет виновную таблицу поимённо
Тест, который пишет в базу и не откатывает за собой, сам остаётся зелёным,
а роняет СОСЕДЕЙ — и обвиняют всегда не того. Так 01.08 девятнадцать чужих
проводок уронили денежную проверку приёмника МТС: искали в приёмнике, а
виновата была рекламная папка рядом.

tools/storozh-chistoty-bazy.mjs спрашивает базу СНАРУЖИ после прогона и
показывает, что осталось. База пересобирается в начале каждого прогона,
поэтому остаток после прогона — вина ровно этого прогона. Минута вместо
двадцати пяти на перебор файлов, и виновная таблица видна поимённо.

Написан по порядку: сперва 11 проверок (краснели, пока кода не было), потом код.

Две вещи сказаны вслух, а не спрятаны:

  - пустой ответ базы — это ОТКАЗ, а не успех. Сторож печатает «проверено
    таблиц: N» и падает, если N нулевое. На этом проекте трижды обжигались
    о сторожей, которые показывали «проверено 0» и это читалось как успех;

  - слепое пятно названо прямо в коде. Справочники, которые кладутся при
    сборке базы, мусором не считаются — значит лишнюю запись ВНУТРИ самого
    справочника сторож пропустит. Поэтому он их показывает списком, чтобы
    дрейф был виден человеку.

Запуск после прогона:
  node tools/storozh-chistoty-bazy.mjs liderra_testing_prospects
Код возврата: 0 чисто, 2 есть остаток, 1 датчик не сработал.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-02 01:16:55 +03:00
Дмитрий 5999707e31 chore: сторож l1-watcher в главной папке позеленел — ruflo описан групповым именем
Сторож требовал, чтобы каждый включённый плагин был поимённо описан в реестре
Прил. Н. ruflo описан там ГРУППОВЫМ именем - одна подсистема, ~20 plugins,
та же модель, что у набора Trail of Bits выше по файлу. Сторож видел только
машинный ключ ruflo-core@ruflo и не мог связать его с групповой записью.
Для ровно таких случаев файл псевдонимов и заведён.

Строки взяты один в один из ветки клиентских СМС, где то же лечение уже
применено 01.08 - чтобы при сведении веток не возникло расхождения.

Приёмка вырезанием, БЕЗ правки чужого settings.json: пробником вызвал
проверяющую функцию сторожа на настоящих данных проекта и подложил в них
выдуманный плагин.
  - как есть: ноль расхождений;
  - выдуманный плагин: пойман;
  - плагин с ТЕМ ЖЕ именем, но из другого источника: тоже пойман.
Третья проверка - главная: она показывает, что псевдоним накрыл ровно один
машинный ключ, а не расширил разрешение на похожие имена.

🔴 Содержательный долг НЕ закрыт и вынесен комментарием прямо в файл:
реестр до сих пор объявляет ruflo «ИЗОЛИРОВАН (dormant) 18.05.2026», хотя
28.07.2026 подсистему разморозили и она включена. Этого расхождения сторож
не проверяет вовсе - чинить через claude-md-management, отдельной работой.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-01 22:07:21 +03:00
Дмитрий 2c270a147b feat: отставание канона схемы стало измеримым одной командой
Долг канона db/schema.sql жил в промтах числом "28 столбцов и 3 таблицы".
Число ЗАНИЖЕНО: оно получено выборочной проверкой нескольких таблиц.
Сплошной замер даёт другую картину.

Канон знает 82 таблицы и 997 столбцов. В базе есть и в каноне отсутствуют
50 таблиц и 8 столбцов. Из 50 таблиц 39 - настоящий долг этой ветки (их
миграция лежит в app/database/migrations), а 11 принесла в местную базу
ветка СМС - их в каноне и не должно быть, пока ветка не сведена.

Отсюда вторая граблина, помимо известной "имя миграции не равно именам
столбцов": по одной живой базе считать тоже нельзя. Местная база копит
таблицы ВСЕХ веток, что на ней гоняли, и без отсечки по наличию миграции
долг завышается на четверть.

Инструмент tools/sverka-kanona-shemy.mjs отвечает на вопрос числом и
поимённо за одну команду. 12 тестов, написаны ДО кода - и это себя
оправдало сразу: черновик разборщика соврал дважды подряд. Сперва он
проваливался в первую же таблицу и не выходил из неё, дав "1 таблица в
каноне" вместо 82. Потом не отличал объявление помесячного куска от
настоящей таблицы. Оба случая закрыты отдельными тестами, оба видел
красными.

Приёмка вырезанием в обе стороны: при наличии долга инструмент возвращает
код 2, на паре без долга - 0.

Закрыт заодно хвост И: четыре обломка убраны из корня в папку мусора
сессии, не удалены. get() оказался НЕ пустым - 69 байт вывода хука,
"0 байт" в прежней записи было неверно.

Промт следующей смене выправлен: пункт А закрыт чужими руками, числа
отставания веток перемерены, вписано решение владельца пока не переводить
общую ветку.

Проверено: тесты инструментов 91 из 91, разметка 0, орфография 0.
NB про орфографию: папка docs/superpowers лежит в исключениях cspell,
поэтому промт сторож орфографии НЕ смотрит вовсе - вчерашнее "орфография
ноль" на нём ничего не доказывало. Ноль выше относится к коду инструмента
и к общему списку слов.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-01 18:16:23 +03:00
Дмитрий 821f966071 fix статанализ: сторож встал ПЕРЕД анализатором и объясняет молчание
Мина из промта подтвердилась, но диагноз вчерашней смены оказался неполным,
а способ её доказательства - неверным. Разбор по замерам.

Что на самом деле убивает статанализ молча - код возврата 1 и ни строки
ни в обычном выводе, ни в канале ошибок:

1. нет файла, перечисленного в scanFiles. Подсказчик _ide_helper_models.php
   собирается на месте, в git его нет, на чистой копии проекта его не будет.
2. метка BOM в начале phpstan.neon. Её ставит Set-Content -Encoding utf8
   в Windows PowerShell 5.1 - то есть любой, кто правит настройку скриптом,
   а не редактором, убивает анализатор. Вчерашнее "доказательство" мины было
   именно этим: временную настройку записали с меткой, молчание списали на
   отсутствующий файл. Причина была другая, вывод совпал случайно.

Третий случай молча не падает, а врёт убедительнее: подсказчик, собранный
без ключа -M, объявляет ПУСТЫЕ копии поверх настоящих моделей. И четвёртый:
подсказчик просто устарел - не знает моделей, появившихся после сборки.
Замер: старый файл знал 52 модели, свежий - 79. Ровно отсюда расхождение
"1865 замечаний в одной рабочей папке против 42 в другой" на одном коде.

Сделано:
- tools/storozh-statanaliza.mjs - сторож на все четыре случая. Называет
  причину человеческим языком и команду починки. Код возврата 2.
- tools/storozh-statanaliza.test.mjs - 13 тестов, писались до сторожа.
- сторож встроен в composer stan и в хук перед larastan через && , так что
  при его срабатывании phpstan не запускается вовсе и не путает человека.
- fail_text у larastan переписан: сначала прочитай, не сказал ли сторож,
  что ошибок в твоём коде нет.
- composer setup и composer ide-helper теперь собирают подсказчик правильным
  ключом. Раньше его нельзя было получить НИ ОДНОЙ описанной командой.
- из baseline убрана устаревшая запись про saas_transactions.credit_target:
  столбец настоящий, миграция от 25.07, свежий подсказчик его знает.
- reportUnmatchedIgnoredErrors выключен с объяснением: записи baseline не
  должны краснеть оттого, что на этой машине подсказчик полнее или беднее.

Датчик свежести намеренно по СОДЕРЖИМОМУ, а не по времени файла. Сначала
сделал по времени - и он тут же закричал "устарел" на неизменившемся коде,
потому что время правки обновляет любая операция git. Заменено на сверку
списка моделей со списком классов-спутников.

Приёмка вырезанием, каждая половина проверена:
- убрал подсказчик -> сторож назвал причину, код 2, phpstan не запускался;
- поставил метку BOM -> назвал её и способ записи без метки;
- подложил подсказчик без -M -> назвал подмену моделей;
- положил старый файл на 52 модели -> перечислил 27 недостающих поимённо;
- вернул всё -> код 0, статанализ ноль замечаний;
- подложил настоящие поломки в tests -> обе пойманы, значит выключение
  reportUnmatchedIgnoredErrors анализатор не ослепило.

Побочно найдено, НЕ закрыто: столбца credit_target нет в db/schema.sql,
хотя миграции на него есть и в CHANGELOG_schema он упомянут. Канон схемы
разошёлся с миграциями - отдельная работа.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-01 17:02:44 +03:00
Дмитрий 8f00449615 fix сторож наблюдателя: не кричим про пропавший хук, когда он на месте
Работа 1 промта от 01.08 — оживление сторожей текста. По ходу вскрылся
отдельный дефект в нашем собственном скрипте.

observer-coverage-checker при коммите из рабочей папки ветки печатал
".git/hooks/post-commit not installed". Файл при этом лежал на месте.
Причина: в рабочей папке ветки .git не папка, а файл-указатель, и проверка
пути <корень>/.git/hooks/post-commit смотрела мимо цели. Плюс настройка
core.hooksPath, которая в этом репозитории задана, вообще не учитывалась.

Класс беды тот же, что уже дважды записан в память: сторож, не умеющий
отличить "нет" от "лежит в другом месте", штампует ложные тревоги. Рядом
в той же строке живёт правдивая жалоба про неподключённый обработчик - и
ложная половина приучает не читать всю строку целиком.

Что сделано:
- добавлена postCommitInstalled: сначала ищет общую папку репозитория
  (для обычной копии это сам .git, для рабочей папки ветки - по указателю
  gitdir и файлу commondir рядом с ним), затем учитывает core.hooksPath
  из config и только потом смотрит наличие файла;
- чистое чтение файлов, без запуска сторонних команд - требование
  Security Guidance 40 для этого скрипта соблюдено.

Порядок работы соблюдён. Пять проверок написаны ДО правки и покраснели
на отсутствующей функции. Разобраны обе стороны каждой развилки: обычная
копия с хуком и без, рабочая папка ветки с хуком и без, перенос хуков
настройкой. Живой прогон по настоящему репозиторию: из рабочей папки
ветки ложная половина ушла, правдивая осталась.

Прогоны: набор проверок инструментов 14 файлов, 66 проверок, все зелёные.

Отдельно, без правок в git: node_modules был в состоянии оборванной
установки - 121 временная папка распаковки, 90 пакетов без главного файла,
у tinyglobby файл обрезан посреди строки. Причина обрыва - падение сборки
better-sqlite3. Пересобрано начисто из списка версий без сборочных
сценариев; package.json и package-lock.json не тронуты, проверено хешем.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-01 15:19:10 +03:00
Дмитрий 2b51ae2754 fix: чистка хвостов коммита 05c22b33 — мусор в словаре и переформатированный chain-map
Два дефекта, внесённых предыдущим коммитом, оба мои:

1. cspell-words.txt — в словарь вместе с четырьмя новыми словами попали
   служебные строки вывода хука: "[INFO] Recording command outcome: cd" и
   "[OK] Command outcome recorded", плюс лишняя пустая строка. Причина —
   дописывание словаря через printf с перенаправлением в конец файла:
   вывод хука приклеился к тому же файлу. Строки удалены, словарь проверен —
   cspell на изменённых файлах даёт 0 ошибок.

2. tools/observer-chain-map.json — файл был переписан скриптом через
   json.dumps с отступом 2, из-за чего компактные однострочные массивы
   развернулись в многострочные: диф раздулся до 180 добавленных и 56
   удалённых строк вместо одной строки по существу. Восстановлено исходное
   компактное оформление, узел grilling вставлен строкой после brainstorming.

Чистый итог обоих файлов против состояния до работы над #90 — четыре слова
в словаре и одна строка в карте цепочек. Проверки: observer-chain-map-checker
OK 17 chains in sync, cspell 0 ошибок.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-28 16:31:36 +03:00
Дмитрий 05c22b3364 feat(инструменты): #90 grilling — допрос по готовому решению + нормативная синхронизация
Зарегистрирован вендоренный скил grilling из mattpocock/skills, MIT,
skills/productivity/grilling. Установлен user-level ~/.claude/skills/grilling/
— вне репозитория, единственная копия: проектная удалена во избежание
задвоения.

Роль — безжалостный допрос по УЖЕ имеющемуся плану или решению: обход дерева
развилок ветка за веткой, по одному вопросу за раз, к каждому вопросу свой
рекомендуемый ответ, факты ищутся самостоятельно, работа не начинается до
явного подтверждения заказчика.

Надстройка проекта поверх немодифицированного тела апстрима, отделена
заголовком:
- протокол docs/grilling/ГГГГ-ММ-ДД-тема.md — разделы Решили / Отрезали и
  почему / Осталось открытым; пишется по ходу, перечитывается после компакта
  контекста. Закрывает класс «договорённость сгорела при компакте»
- порядок обхода «сначала необратимое» — деньги, схема БД, что уходит клиенту
- критерий остановки: пустой фронт развилок с объявлением вслух
- «слушай, не защищай»

Граница ADR-021 GR1 с #55 discovery-interview — разрез по наличию решения:
grilling куёт решение, которое у заказчика уже есть, поэтому наводящий
рекомендуемый ответ обязателен; discovery-interview вскрывает проблему, когда
решения ещё нет, и там наводящие ответы запрещены. GR2 — граница с
brainstorming #19. GR3 — вендоринг без модификации апстрима.

Реестр: узел #90 + контракт, связка L1 между brainstorming и writing-plans,
классификация planning вес 0.8 — ниже первичных решателей. Автотаблицы
перегенерированы через registry-render, карта цепочек дополнена.

Нормативная синхронизация квинтета:
- Tooling Прил. Н v2.26 — новый §4.63, счётчик 87→88 и 107→108, off-phase
  +57→+58, футер
- Pravila v1.45 — §13.2 новый абзац, запись в истории версий
- PSR_v1 v3.25 — R10.1 Блок 1 note, запись в истории версий
- CLAUDE.md v2.49 — через плагин claude-md-management, §0 версии квинтета,
  §3.4 +#90, §9 запись

Попутно снят застарелый рассинхрон шапки Tooling: числа 84/104 остались от
майской версии, приведены к 88/108, дописаны research-tooling и узлы #87–#90.

Проверки: registry-render --check зелёный на обоих файлах,
observer-chain-map-checker OK 17 chains in sync, загрузчик видит 90 узлов,
markdownlint 0 ошибок, cspell 0 ошибок.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-28 16:16:25 +03:00
Дмитрий 2493630249 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
Дмитрий 9d8188cd65 feat: wall - подписанные строки вердиктов роутера наставника и судьи во всплытии
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 13:16:32 +03:00
Дмитрий b1795b7153 chore(router): судья/наставник/роутер переведены на deepseek-v4-flash
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 11:08:15 +03:00
Дмитрий 59831cf7dc imitation phase1 merge
# Conflicts:
#	app/app/Console/Commands/PhoneRangesImportCommand.php
#	app/app/Jobs/RouteSupplierLeadJob.php
#	app/app/Services/LeadRegionResolver.php
#	app/database/migrations/2026_05_31_100000_create_phone_ranges_and_resolution_log.php
#	app/tests/Feature/Console/PhoneRangesImportCommandTest.php
#	app/tests/Feature/Jobs/RouteSupplierLeadJobTest.php
#	app/tests/Feature/PartitionsCreateMonthsTest.php
#	cspell-words.txt
#	docs/observer/STATUS.md
#	tools/enforce-powershell-gate.test.mjs
#	tools/enforce-router-gate.mjs
#	tools/enforce-router-gate.test.mjs
#	tools/enforce-tdd-gate.test.mjs
#	tools/enforce-tdd-real-test-verifier.mjs
#	tools/enforce-tdd-real-test-verifier.test.mjs
#	tools/enforce-verify-record.test.mjs
#	tools/mcp-tool-classifier.test.mjs
#	tools/shell-content-rules.test.mjs
2026-06-17 08:03:35 +03:00
Дмитрий f67acb2186 feat router-mentor: arbitration fixes 1+2+3 - verdict visibility, round-memory judge-self-history and mentor-re-eval, owner-seal arbitration; 29/29 tools green
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 11:13:52 +03:00
Дмитрий 9a4ccbb7e3 fix router-mentor: router-classifier per-attempt timeout 30s -> 300s for DeepSeek; prevents Agent Router calls being truncated and hanging in aitunnel logs
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 17:32:06 +03:00
Дмитрий 2f777007bf chore router-mentor: control LLM claude-sonnet-4-6 -> deepseek-v4-pro via aitunnel; HEAVY_LLM_TIMEOUT_MS 90s->300s; fix reasoning content-block text extraction in callAnthropicAPI
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 17:00:35 +03:00
Дмитрий c7762b2d38 chore: prune brain test-layer to claude-brain
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 05:03:55 +03:00
Дмитрий cdd3cbfa3b feat: research-tooling Perplexity Pack #87-89 — registry/router/normative sync + ADR-019
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 15:44:42 +03:00
Дмитрий 9d9553d863 fix(research-tooling): gate read_only + perplexity via aitunnel base URL
Закрывает spec-gap Perplexity Pack — enforce-mcp-classification default-блокировал
неклассифицированные MCP-инструменты. Добавлены mcp__perplexity__*, mcp__exa__*,
mcp__firecrawl__* как read_only (ADR-019 постура, решение владельца 2026-06-14).
TDD RED-GREEN, регрессия tools-only 3931 passed / 2 skip.

.mcp.json: PERPLEXITY_BASE_URL=https://api.aitunnel.ru/v1 — роутинг sonar через AITUNNEL.
Live-smoke перезапуском: perplexity (sonar-pro), exa, firecrawl — все три GREEN.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 13:57:41 +03:00
Дмитрий 052078c3cf 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
Дмитрий 23c3224413 fix(router-mentor): per-attempt таймаут тяжёлых LLM-вызовов 30с→90с
Судья/наставник по большой спеке/плану отвечают 25-32с; дефолт callAnthropicAPI 30с давал таймаут→degraded→печать не вставала (спека не запечатывалась gate1 → план не мог встать gate2). HEAVY_LLM_TIMEOUT_MS=90с в router-config, проброшен в callJudgeModel (судья) и buildLlmCall (наставник). TDD RED→GREEN, регрессия tools-only 3928 passed + 2 skipped.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 09:54:04 +03:00
Дмитрий 4f9d735e4d 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
Дмитрий ad76cdf496 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
Дмитрий e0442ef71c 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
Дмитрий 37ce1ae2ea feat(wall): оркестратор наставник-судья - строгая последовательность печати
Новый enforce-mentor-then-judge.mjs запускает наставника дочерним процессом до конца, потом судью (свежий mentor-GO/вердикт) - убирает гонку параллельных PostToolUse-хуков. Машины enforce-mentor-on-plan-write/enforce-judge-gate байт-в-байт не тронуты. Зарегистрирован в settings.json. TDD +5 тестов.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-13 17:15:37 +03:00
Дмитрий 903a450fa6 fix(mentor): резолв ID узлов в имена в скил-контексте наставника
renderSkillContext резолвит #N -> '#N - имя' через registry.indexById (resolveNodeName, fail-safe -> голый #N); onPlanWrite прокидывает registry. Наставник видит рекомендацию роутера именами. TDD +4 теста, регрессия tools-only 3910 GREEN.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-13 17:15:14 +03:00
Дмитрий cd1c460911 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
Дмитрий 2a50c91882 feat(mentor): degraded-судья диагностируем — cause(no_key/transport_error)+errorType+at
Разбор «перемежающегося degraded судьи» по systematic-debugging: действующего
бага нет (ключ SET, 28/28 вердиктов чистые, degraded-строки несверяемы — at:null,
без парного WARN). Гипотеза «retry/таймаут» не подтверждена → таймаут не трогали.

Вместо этого закрыта слепота диагностики (TDD, под maintenance):
- callJudgeModel различает no_key vs transport_error+errorType (classifyLLMError);
- причина протекает в вердикт → warnJudgeUnavailable (+cause/error_type/at) и seal-запись;
- main() передаёт nowMs: Date.now() → seal/verdict/warn больше не at:null (логи сверяемы).

Файлы: tools/seal-log.mjs, tools/enforce-judge-gate.mjs. +9 тестов; 2 exact-match
приведены к новому контракту. Регрессия tools-only 3829 GREEN (база 3820), 0 регрессий.
cspell-words.txt +8 терминов. Роадмап: секция «Печать M7» + degraded-наблюдаемость.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-13 04:12:53 +03:00
Дмитрий 9f99b4ead4 fix(mentor): печать плана M7 — снять дедлок судья↔наставник + наблюдаемость seal-attempts 2026-06-13 03:40:20 +03:00
Дмитрий 27082a42de feat(mentor): wire mentor surface + counter + escalation card (wave 7) 2026-06-12 19:09:59 +03:00
Дмитрий 31e044d6d5 feat(mentor): wire judge escalation to arbitration card (wave 6) 2026-06-12 19:03:59 +03:00
Дмитрий c3e72f6a54 feat(mentor): objection-format judge+mentor formatters (waves 4-5) - 9 tests green 2026-06-12 18:43:43 +03:00
Дмитрий 75b832ad9e feat(mentor): negotiation-section parser (wave 3) - 4 tests green 2026-06-12 18:30:05 +03:00
Дмитрий d0d175c9b6 feat(mentor): arbitration-card pure builder (wave 2) - 6 tests green 2026-06-12 18:26:17 +03:00
Дмитрий 0192576901 fix(verify): produce-verify-receipt Windows execFileSync npx to execSync 2026-06-12 18:07:21 +03:00
Дмитрий 9eeb23073d feat(mentor): mentor NO-GO counter L1 (wave 1) - 3 tests green 2026-06-12 17:59:24 +03:00
Дмитрий 09620f368e feat(m7): re-plan на ходу (impl-карвут) + эскалация судьи (escape-honor + счётчик NO-GO) + docs-хвост 2026-06-12 15:48:17 +03:00
Дмитрий b8684db135 feat(m7-phase8): sealedPlanCoversEdit live-wiring + matcher extension to discipline sources
planCoversAction (signed-plan + tree-valid + leaf-match, fail-CLOSED) wires the §6
build-loop differentiator live. main() matcher now fires for tools/enforce-*.mjs
(ad-hoc → LAW/escape; under sealed plan → CARD). decide() skips doc-malice prose
layers for code and allows build-loop CARD (M2/content-floor/TDD govern). Hook inert
until Phase 8 registration. +10 tests; regression tools-only 3397 passed / 2 skip.

Plan: docs/superpowers/plans/2026-06-08-router-mentor-machine-7-phase-5.md (Deferred Ф8).

B
2026-06-12 11:28:58 +03:00
Дмитрий fb4f179bb1 chore(mentor): роадмап эпика 2026-06-12 + env ROUTER_LLM_BASE_URL в observer-self-assessment-api (зеркало транспорт-фикса, TDD) + cspell словоформы. Регрессия tools 3754 GREEN 2026-06-12 08:14:35 +03:00
Дмитрий 6af37af7c0 fix(mentor): smoke этап 4 пройден — деталь ошибки транспорта в catch вердикта + env ROUTER_LLM_BASE_URL в дефолте callAnthropicAPI (смена оператора на aitunnel) + контракт массива строк в промпте plan_points_addressed (F-C3); runbook этап 4 + env-таблица + блок смены оператора; smoke-план; cspell +aitunnel и словоформы. Регрессия tools 3753 GREEN 2026-06-12 07:55:31 +03:00
Дмитрий dc93e7eab5 feat(strict-llm-keys): оба строго — судья только ROUTER_JUDGE_LLM_KEY, наставник только ROUTER_MENTOR_LLM_KEY, общий ROUTER_LLM_KEY не фолбэк (решение владельца 2026-06-12; resolveJudgeLlmKey/resolveMentorLlmKey + env-тесты строгости + runbook-таблица ключей) 2026-06-12 06:39:17 +03:00
Дмитрий 5fba781936 feat(mentor-activation): активационная обёртка наставника — рубильник SEAM + journal/verdict store + export PLAN_PATH_RE + контекст-в-плане + producer-хук PostToolUse + freeze-gate зубы в печать судьи (план T1-T7 + sharp-edges W-1..W-4) 2026-06-12 05:51:41 +03:00
Дмитрий 142e620531 fix(mentor-finreview): финревью Фазы B 5-скил — FR-1 freeze-gate VF-1/SE-A1 inline + FR-2 единый рендер районов/staleness (W1-канон) + FR-4 balanced-парс JSON + VA-1 единый рендер контекста/ДР-1 + VA-2 маркер КОНТЕКСТ ПУСТ + VA-3 валидация request_district + F-C2-6/W7 ноты 2026-06-11 20:10:42 +03:00
Дмитрий 051583d180 feat(completeness-radars): радары полноты — graph-radar (соседи по links, слепота видна) + skeleton-radar (отчёт по каждому заголовку, молчание=not-reported) + freeze L2-пол (нах.F2, sub-plan F Tasks 1-3 + sharp-edges F-F1..F-F5) 2026-06-11 19:31:04 +03:00
Дмитрий 05714e978d 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
Дмитрий d1bde4050a feat(mentor-live-seam): живой шов наставника — task-id O17 + tamper-evident журнал + вердикт-производитель C-1/F4 + runMentorRound/петля/F7 + freeze-gate VA-8/O2/VA-9 (sub-plan C Tasks 1-7 + A1-A8 + Д-1а/Д-2а/Д-3 + sharp-edges F-C1..F-C7) 2026-06-11 18:13:45 +03:00
Дмитрий 82af79db11 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
Дмитрий 3f0e506c9a feat(reading-discipline): дисциплина чтения наставника — тип/вид/гейт ДР-1/read-LOG/probe-cap (sub-plan D Tasks 1-8 + SE4/SE5/SE12/V-3 + sharp-edges F-D1..F-D7) 2026-06-11 16:46:56 +03:00
Дмитрий 0b43563dca feat(project-graph): слоистый граф районов + staleness O16 (sub-plan B Tasks 1-8 + SE7/SE8/SE11/V-3 + sharp-edges B1/B3) 2026-06-11 15:52:12 +03:00
Дмитрий a7a58b055f fix(context-verity): MIN_ANCHOR_LENGTH=4 порог anchor (SE-A2) + коллатераль тестов 2026-06-11 15:07:14 +03:00