Skip to content

Releases

v0.19.0

Choose a tag to compare

@github-actions github-actions released this 27 Sep 14:21

Выпуск про одно: «поставил» не значит «работает» — и AQK теперь говорит, что поставить.
aqk adopt засчитывает проверку, только если она объявлена, краснеет на заведомом браке и идёт
в конвейере. doctor называет инструменты, которые подходят проекту и нигде не стоят, — словами
человека и с командой установки, — и показывает, какие правила .aqk/rules держит проверка, а
какие только человек. Про четырнадцать сторонних инструментов AQK знает, как каждый незаметно
выключают, — по их официальной документации, с дословной цитатой.

Что может выглядеть иначе после обновления. В doctor два новых блока: сводка по папке
правил («держит проверка — N, человек — M» и команды aqk add для обещанных, но не поставленных
проверок) и «Что ещё стоит поставить». Если npx не смог запустить инструмент (нет сети, нет
прав на кеш), гейт отвечает «не смогли проверить» (код 2), а не «находка». entry-commands-exist
в проекте на CMake или autotools пишет «цели make не проверены» вместо обвинения. Правила в
.aqk/rules несут пометки <!-- aqk: … -->; чтобы обновить уже разложенные копии, удалите папку
.aqk/rules и запустите aqk init — без --force, он перезаписывает и .aqk.yml.

Добавлено

  • doctor советует, что поставить, — словами человека. Блок «Что ещё стоит поставить»: до
    трёх инструментов вне каталога, которые подходят репозиторию по его признакам и не стоят ни в
    одной проверке, — что поймает, как поставить и как доказать (aqk adopt). Пример: «schemathesis —
    есть описание API — расхождение API с его описанием…». Попутно найдено: у axe и k6 в условии стояли
    признаки, которых doctor не вычисляет (has_frontend, has_server), — совет по ним не сработал
    бы никогда; теперь это сторожит приёмка units-tools.mjs. Новый признак has_gh_actions (zizmor
    проверяет только GitHub Actions).
  • У каждого правила .aqk/rules назван сторож, и doctor говорит, чего не хватает. 47 правил
    размечены <!-- aqk: … -->: 12 держит запись каталога, 35 — человек. doctor печатает сводку и
    по каждой обещанной правилами проверке, которой нет в манифесте, — команду aqk add. Разметку
    сторожит units-rules.mjs: пометка обязана вести в существующую запись, русская и английская
    копии — совпадать. Повод — замеры 2026 года: правило текстом агент соблюдает всё хуже с каждой
    новой функцией, а файлы правил не поднимают долю решённых задач.
  • Две новые методички. engineering-glossary.md — словарь понятий, которыми ставят задачу
    агенту и проверяют его код (связанность, DRY, идемпотентность, N+1, законы Люссера, Гудхарта,
    Конвея, Хайрама, рамки RED/USE/DORA, 29 признанных стандартов). agent-evaluation-2026-06.md —
    исследования весны 2026 о подгонке под проверку: названия всех работ arXiv сверены заново, три
    числа поправлены по аннотациям.
  • Гейт private-names — закрытые проекты владельца не попадают в публичный репозиторий.
    Сверяет каждое слово файлов с отпечатками SHA-256 запрещённых имён: самих имён в репозитории нет,
    и в выводе слово не печатается. Сверка нашла 83 упоминания закрытого проекта в текущих файлах —
    убраны; снимок его проверок (kit/docs/ai/quality-gates-checklist.md) удалён целиком.
  • JavaScript комплекта — под biome (гейт biome, tool/selfcheck/biome.sh, biome.json).
    Выбран замером на tool/: eslint с рекомендуемыми правилами — 50 замечаний, biome — 88, из них
    43 про оформление; по сути оба нашли одно. biome — одна программа без пакетов в нашем
    package.json. Правила оформления выключены, предупреждения считаются находками
    (--error-on-warnings). Неиспользуемые импорты (9) и переменные (2) убраны сразу, остальные 36
    замечаний — долг под храповиком.
  • Скрипты оболочки комплекта — под shellcheck (гейт shellcheck, tool/selfcheck/shellcheck.sh).
    Первый прогон: 88 замечаний. Две ошибки исправлены сразу, одна из них настоящая — в
    research/corpus/handwritten-vs-generated.sh here-документ перебивал трубу, и скрипт насчитывал
    ноль рукописных копий при любых данных (результат нигде не опубликован). Остальное — долг под
    храповиком ratchets/shellcheck.txt: новое замечание не пройдёт. Сведения о shellcheck — в
    kit/tools/: порог -S error прячет предупреждения, в том числе подстановку без кавычек.
  • Поле манифеста own_samples: — образцы проверок, написанных самим проектом. npm test,
    make check, свои скрипты доказываются по <own_samples>/<имя>/red|green, отдельно от
    каталога записей (samples:): там образец своей проверки читался бы как новая запись. Так же
    принято снаружи — у semgrep тест правила лежит рядом с правилом. У самого AQK: checks/gates,
    образцы для всех семи собственных прогонов и для dead-code — все 31 гейт комплекта
    доказаны. Свои образцы берутся раньше образцов каталога: запись бывает поставлена не тем
    рецептом, под который написаны её образцы (у нас dead-code на knip, а образцы записи —
    питоновские).
  • Доказательство подсадкой — только в aqk prove и aqk adopt. doctor --run, badge и
    report его пропускают и называют это: копия проекта и три прогона гейта втрое дороже самого
    гейта (на AQK — 3 с → 22 с). В нашем конвейере prove идёт отдельным шагом задания check, и
    общее время от этого не растёт — его задаёт задание windows.
  • prove доказывает любую команду проекта, а не только команду из каталога. Раньше
    npm run lint, make check, ruff check со своим конфигом назывались «недоказуемыми»:
    подставить каталог образца было некуда. Теперь дерево красного образца кладётся по своим путям
    в копию проекта, команда идёт как есть и обязана покраснеть; на зелёном — промолчать. Копия
    сначала проверяется чистой: команда, красная без подсадки, называется отдельной причиной.
    Рабочее дерево не меняется.
  • aqk adopt <гейт> — договор установки: «поставил» не значит «работает». Код 0, только
    если гейт объявлен, у него есть красный и зелёный образцы, он доказан на них и идёт в
    конвейере. Для каждого непройденного шага — что именно сделать и куда положить. «Прочитать
    официальную документацию» печатается шагом для агента и не засчитывается: машина его не
    проверяет. Повод — замер того же дня: Stryker по умолчанию не роняет сборку никогда
    (thresholds.break: null), и у 96 из 149 настоящих файлов его настроек на GitHub порога нет.
    Сводка для агента теперь велит adopt после любой установки инструмента.
  • Сведения о сторонних инструментах — kit/tools/: ruff, eslint, biome, knip, Stryker, jscpd, vulture, gitleaks, zizmor, mutmut, schemathesis, k6, axe. adopt опознаёт
    инструмент по команде гейта (и по скрипту package.json, который она зовёт) и говорит, не
    заглушён ли он: ruff --exit-zero, ruff check --fix без --exit-non-zero-on-fix, ruff format без --check, eslint с правилами warn и без --max-warnings 0, eslint с
    --no-error-on-unmatched-pattern; biome с правилами warn без --error-on-warnings, правила
    info (не роняют никогда), --no-errors-on-unmatched, --skip-parse-errors; knip с
    --no-exit-code или --max-issues больше нуля; Stryker без thresholds.break (задаётся только в
    файле настроек — из команды его не передать) и с allowEmpty; jscpd с --exit-code 0 и без
    --fail-on-empty; vulture с --min-confidence выше 60 (прячет все неиспользуемые функции и
    классы); gitleaks с --exit-code 0; zizmor с --no-exit-codes, --format=sarif и --fix.
    mutmut не роняет проверку ни при каком числе выживших мутантов — документация об этом молчит,
    установлено замером (mutmut 3.8.0: run и results выходят с нулём), и правило помечено как
    замер, а не цитата; в починке — обёртка, проверенная на том же проекте. schemathesis, сужённый
    до --checks not_a_server_error; k6 без thresholds в скрипте теста (скрипт читается по пути из
    команды) и с --no-thresholds; axe без --exit.
    Каждое правило — с дословной цитатой из официальной
    документации и адресом; цитаты сверяет с исходником tool/selfcheck/tools-quotes.mjs, примеры
    каждого правила прогоняет units-tools.mjs.

Изменено

  • Пуш и выпуск быстрее, проверок столько же. smoke.sh запускает свои две части — 113
    проверок оболочки и 192 проверки node --test — одновременно, а не одну за другой: локально
    98 → ≈70 с, счёт тот же, 305. Конвейер на Windows разложен на три параллельных задания
    (каталог, две части smoke) вместо одного одиннадцатиминутного. Выпуск больше не повторяет
    прогон гейтов, а требует зелёного конвейера на этом же коммите — то есть ещё и Windows с
    образом, которых прежний шаг выпуска не смотрел.

Исправлено

  • checkwash поднят с 0.3.4 до 0.4.2 — в конвейере и локально. 0.3.4 объявлял «тест пропал»,
    когда в файл тестов добавляли случаи в массив; в 0.4.2 этого нет, образцы записи
    test-not-adjusted на новой версии доказаны заново (aqk adopt).
  • entry-commands-exist больше не обвиняет проект на CMake. Если Makefile создаёт генератор
    сборки (CMake, autotools), цели make называются «не проверены», а не «нет такой цели»; общее
    правило %: (Makefile Sphinx) принимает любую цель; «make» в комментарии # внутри блока кода —
    текст. Найдено при подготовке письма в чужой репозиторий: все четыре находки оказались ложными.
  • aqk prove больше не подписывает сбой проверки как «команда пустая»: это «НЕ СМОГЛИ доказать —
    сбой самой проверки», жёлтым, с причиной и хвостом вывода — как и «красная без подсадки».
  • npm, не сумевший запустить инструмент, — «не смогли проверить», а не находка. npx knip
    без кеша (контейнер без домашнего каталога), без сети или с недоступным реестром выходит с кодом
    1 — тем же, каким knip сообщает о мёртвом коде, и AQK объявлял исправный гейт сломанным.
    Подпись собственной неудачи npm — npm error code E… (npm ERR! code E… у старых версий), кроме
    ELIFECYCLE: так старый npm подписывает упавший скрипт, то есть находку. Правило в двух копиях —
    tool/lib/execution.mjs и kit/gates/_native.sh, сверка в `smoke/gate-errors.test....
Read more

v0.18.0

Choose a tag to compare

@github-actions github-actions released this 26 Sep 19:25

Выпуск про одно: AQK говорит «всё хорошо» только тогда, когда у него есть на это основание.
Пустой прогон, урезанный прогон, проверка, которой нечего было смотреть, и подменённая команда
гейта раньше выглядели как чистый результат — теперь каждое названо своим словом. И впервые
у человека есть отчёт одной страницей: что защищено, ловит ли защита на деле, лучше или хуже,
чем в прошлый раз, и какие красные новые, а какие висят давно.

Что может выглядеть иначе после обновления. Под галочками появятся строки «пусто: …» у
гейтов, которым нечего было проверять, — прогон при этом зелёный. protection-not-removed на
снимке без команд печатает совет «подмену команды не вижу»; aqk add любого гейта дописывает
строки команд в снимок, и после этого смена команды гейта без правки снимка — красная. Прогон
с --only/--skip называет себя урезанным, а не «всё объявленное зелёное». doctor --run
пишет .aqk/history.jsonl и .aqk/report.html.

Добавлено

  • README стал коротким: что это, кому и когда, запуск за минуту, установка. Около ста строк
    вместо семисот, логотип в начале. Всё прежнее содержание — целиком в полном руководстве
    docs/guide.md и docs/guide.ru.md; версии и размер пакета в них сверяются той же проверкой,
    что и в README.
  • Новое отдельно от давнего. doctor --run, блок для агента, отчёт для человека и сводка
    задания делят не зелёные гейты на сломанные только что («новое с прошлого зелёного») и
    висящие давно («красный с 13.09, 20 прогонов подряд»). Возраст считается по истории прогонов.
    Повод — отзыв с проекта владельца: давний долг прятал три свежие ошибки, и то, что AQK
    поймал сам, никто не заметил.
  • Отчёт для человека одной страницей — .aqk/report.html. Три ответа на одном экране: что
    защищено, ловит ли защита на деле (по пробе), лучше или хуже, чем в прошлый раз, — и что
    поручить агенту, готовыми командами. doctor --run пишет его каждый раз, aqk report --html
    собирает без прогона. Один файл без сети и зависимостей. Блок для агента велит показать его
    человеку. В GitHub Actions тот же прогон дописывает сводку задания (GITHUB_STEP_SUMMARY) —
    без прав и без нашего действия.
  • История прогонов — .aqk/history.jsonl. Строка на прогон: коммит, уровень, итог каждой
    проверки и пометка урезанного прогона. Из неё отчёт считает «было → стало» по двум последним
    полным прогонам и называет, что сломалось и что починено.

Исправлено

  • Подмена команды гейта при том же имени больше не проходит зелёной. В одном PR команду
    secrets-not-in-code заменили на "true" и добавили в код ключ — doctor --run говорил
    «всё объявленное зелёное», код 0: protection-not-removed сторожил только имена. Теперь снимок
    gates-declared.txt хранит одобренную команду строкой # run имя: команда, и расхождение с
    манифестом красное, с «было» и «стало». Сменить команду можно правкой этой строки — её видно
    в дифе. Снимок старого формата не роняет прогон, а говорит советом, что подмену не видит;
    aqk add любого гейта дописывает недостающие строки и не переписывает записанные. Найдено
    сверкой с судьёй kirder24-code/ai-agent-manager (цикл A5).
  • Урезанный прогон называет себя урезанным. doctor --run --only … при незапущенном
    красном гейте печатал «не запускались: …» и тут же «Всё объявленное зелёное.»; заголовок
    отчёта говорил то же. Теперь — «Всё запущенное зелёное, но прогон урезан: не запускались …».
  • Прогон без единого гейта не называется зелёным. Вместо «Всё объявленное зелёное» —
    «пусто: гейтов не объявлено — прогонять было нечего».
  • «Пусто» больше не выдаётся за «чисто». Сканирующий гейт, не нашедший ни одного файла
    своего типа, молчал с кодом 0 — так же, как на проверенном и чистом проекте (10 из 13
    записей). Теперь он печатает «пусто: … — проверять было нечего», остаётся зелёным, а
    doctor --run показывает строку под галочкой. Если файлы скрыл .aqkignore, это названо.
    env-secrets-not-committed и personal-config-not-shared «пусто» не говорят: для них
    отсутствие файлов и есть чистый ответ.
  • Код в vendor/, coverage/ и других пропускаемых каталогах больше не определяет язык
    проекта.
    Список пропусков был записан дважды — сорок имён у гейтов, восемь у определения
    языков, — и doctor советовал записи по файлам, которые сами записи не читают. Теперь список
    один, в kit/gates/_skip.sh.
  • Осознанно снятая защита снова видна. protection-not-removed печатал «совет: снято
    осознанно …» с кодом 0, а прогон у зелёного гейта показывает только строки-советы и узнавал
    одну метку «почини:». Строка не доходила до человека. Теперь узнаются обе, а модульная
    проверка сверяет каждую метку, которую печатают гейты, с тем, что узнаёт прогон.
  • Неизвестное время гейта в отчёте — прочерк, а не «0.0 с». Строки истории старше поля
    времени показывались нулём, то есть «гейт отработал мгновенно». Единица времени теперь на языке
    отчёта: в английский попадала русская «с».
  • Время в отчёте — местное. Шапка и подписи графика показывали время по Гринвичу: прогон в
    18:47 выглядел как 13:47, то есть как чужой.
  • Мусорный предел больше не выключает гейт. AQK_MAX_DEPTH=abc у complexity-limit и
    AQK_DUP_LINES=abc или -3 у duplicate-code давали зелёный на заведомом браке без единой
    строки. Теперь — код 2, «проверка не состоялась», с именем переменной.
  • deps-are-pinned видит обычный package.json и конвейер, выключивший lock-файл. Первая
    зависимость на новой строке принималась за «зависимостей нет». Теперь ещё и pnpm install --no-frozen-lockfile в .github/workflows при pnpm-lock.yaml — находка с файлом и строкой.
  • Порог --min из мусора — отказ до прогона. --min -1 проходил при любом уровне, --min ""
    становился нулём. Теперь допустима только ступень от 0 до верхней, как у --jobs.
  • Кэш ruff больше не отдаёт вчерашнее «чисто». Ключ его кэша — время изменения файла: правка,
    после которой время вернули прежним (cp -p, tar, unzip), проходила гейт. У рецептов ruff
    теперь --no-cache.
  • Конфигурация анализатора больше не выключает объявленный гейт. Исключение пути в конфиге
    ruff, pylint и vulture снимало находку при нарушении в коде; рецепты теперь отменяют его.
  • Переписанное ожидание теста называется вслух, а прогон предупреждает, когда индекс и рабочая
    копия расходятся: зелёный вердикт относился бы не к тому, что уйдёт в коммит.
npx agent-quality-kit doctor

v0.17.0

Choose a tag to compare

@github-actions github-actions released this 24 Sep 04:57

Выпуск про одно: зелёный результат больше не скрывает сломанный прибор. Авария анализатора,
недоступная история и неверный путь Git-хука теперь отделены от чистого результата; новый гейт
ловит разъехавшиеся копии сводов агента; проверки конвейера видят трубы и husky-хуки, которые
гасят провал.

Что может выглядеть иначе после обновления. test-not-adjusted вернёт ошибку проверки, если
указанной базы нет или она не является коммитом. Native-анализатор, завершившийся аварийно, не
позеленеет после фильтрации знакомого долга. aqk ratchet не создаст baseline из неполного
аварийного вывода. Проект с двумя похожими корневыми сводами агента получит находку, только если
они действительно разошлись; указатель одного файла на другой и независимые документы не
обвиняются.

Добавлено

  • entry-docs-agree — разъехавшиеся копии AGENTS.md и CLAUDE.md видны машине. Порог
    проверен на 85 парах из 300 чужих репозиториев: четыре находки разобраны вручную, ложных среди
    них нет. Указатели вида @AGENTS.md, отличие только в имени агента и два самостоятельных
    документа проходят.
  • Постоянная запись храповика ~ <ключ>. Нестабильная находка больше не исчезает после
    одного тихого прогона; рядом обязательна причина # постоянная: ..., а снимает запись человек.
  • Проверка недоказанных рецептов каталога. Приёмка теперь поимённо показывает рецепты, для
    которых нет собственного красного и зелёного образца, вместо молчаливого впечатления полной
    доказанности.

Исправлено

  • Авария анализатора не превращается в успех после фильтрации. Общая shell-классификация
    различает чистый результат, находку и отказ прибора до фильтра путей и baseline. Храповик
    сохраняется побайтово при ошибке, а создание baseline запрещено. Shell- и Node-реализации
    сверены на всех 256 кодах завершения для пяти инструментов.
  • test-not-adjusted больше не зеленеет без доступной базы сравнения. Неверный ref и объект,
    который не является коммитом, дают отдельный исход «проверка не состоялась».
  • Git-хук ставится в настоящий путь Git. Учитываются worktree и core.hooksPath, включая
    относительный и абсолютный путь; чужой существующий хук не переписывается.
  • Отпечаток доказательства не склеивает разные входы. Отсутствующий файл, буквальный текст
    <missing> и границы записей кодируются раздельно.
  • ci-actually-fails видит погашенный провал в трубе и husky-хуке. pytest | tee без
    pipefail, а также lint-staged || true в блокирующем хуке больше не выглядят защитой.
  • aqk note коммитит только свой журнал и не пушит без --push. Чужой staged-дифф не
    захватывается, внешнее действие требует явного флага.
  • Советы выбираются по основному языку проекта. Служебные скрипты больше не заставляют
    ставить Python-рецепт в C#- или Go-проект; порог снят с 35 чужих репозиториев.
  • Сверка covers не подтверждает выключенное правило линтера. ignore, off и 0
    учитываются, а итоговые корзины считаются по фактическому вердикту.
  • Baseline называет свою границу. Число применимых проверок описано как оснащение для работы
    машины, а не оценка качества проекта.

Исследовано и отклонено

  • Разобраны все 129 правил glint и каталоги популярных линтеров; новые записи без подтверждённого
    живого класса в AQK не добавлялись.
  • Форма «ошибка напечатана, процесс вернул 0» проверена на 61 репозитории: подтверждённых случаев
    нет, поэтому гейт по одной правдоподобной идее не создан.
  • Полностью прочитан smixs/code-quality; внедрены только механизмы, для которых воспроизведён
    собственный дефект AQK. Остаток первого исследовательского цикла честно остаётся в roadmap.
npx agent-quality-kit doctor

v0.16.0

Choose a tag to compare

@github-actions github-actions released this 16 Sep 07:39
87c5f06

Выпуск про одно: комплект перестал верить сам себе на слово. Десять раз наши собственные
утверждения не пережили проверки — и каждый раз побеждала проверка.

Сперва четыре случая, где мы обвиняли или молчали напрасно:

  • doctor при первой встрече с чужим проектом ставил зелёную галочку проверке, выключенной
    прямо в её же строке (node --test || true). Теперь читает тело скрипта, а не имя;
  • гейт hook-actually-fires зеленел на хуках, указывающих на скрипты, которых нет. Нашёл это
    чужой линтер, прогнанный по нам, а не наши 192 проверки;
  • гейт ci-actually-fails обвинял напрасно: замер на 70 чужих конвейерах дал одно срабатывание,
    и оно оказалось ложным;
  • сканер чужих репозиториев нашёл ещё три ложных — и все три починены раньше, чем ушло хоть
    одно письмо.

Затем шесть — все одного рода: правило написано для чужих и не применено к себе. Их нашла
попытка поставить комплект в большой зрелый проект, а не наш прогон из двух сотен проверок. Они
разобраны ниже по одному; короче всего так: объявленный гейт делал чужие проверки невидимыми,
vitals засчитывал чужой хук за наш, smoke.sh выдавал запрет среды за пятнадцать падений,
предел времени гейта жил в четырёх копиях без способа решить иначе, report падал там, где
нечего записать, а requires был доступен нашим записям и недоступен гейтам проекта.

Что может выглядеть иначе после обновления. Если в вашем package.json проверка выключена в
самой команде (|| true, --exit-zero, тело из одной печати), doctor теперь скажет об этом
крестом и не предложит вписывать её в манифест. Если у вас объявлены хуки Claude Code, чьи файлы
отсутствуют, hook-actually-fires покраснеет — раньше молчал. Если у вас есть свои проверки в
Makefile, package.json или .pre-commit-config.yaml, doctor назовёт их и тогда, когда
гейты уже объявлены, — раньше он о них молчал. Если AQK не вызывается из вашего
.git/hooks/pre-commit, vitals скажет об этом прямо, а не напишет «прописан». Все перемены в
одну сторону: инструмент стал говорить там, где раньше молчал.

Удалено

  • Записи entry-links-exist и no-phantom-package убраны из каталога. Обе читали свободный
    текст, а не опознавали конструкцию: разметку и прозу вокруг команд установки. Замер по 400
    чужим репозиториям 2026-09-14/15 дал у них двенадцать ложных срабатываний и ни одной
    подтверждённой настоящей находки. Хрупкую запись не чинят, её убирают — иначе каждый следующий
    замер приносит новое исключение, а доверие к остальным записям падает вместе с ней. Правило,
    по которому это решено, записано в SPEC.md §6

Исправлено

  • Объявленный гейт больше не прячет проверки, которые у проекта уже есть. Замер 2026-09-16
    по двенадцати чужим репозиториям: у шести зрелых (requests, httpx, fastapi, black,
    express, flask) doctor читал в их файлах от одной до трёх настоящих проверок — и всё
    исчезало, стоило объявить ОДИН гейт. Итог говорил «держит машина 0» проекту с настоящим
    pre-commit и Makefile: чем больше человек настроил, тем меньше мы о нём знали. Отсев теперь
    по КОМАНДЕ, а не по факту «манифест не пуст»: имена гейтов у проекта свои, по ним совпадения
    не будет никогда. Это вторая встреча с тем же классом — первый чужой пользователь назвал
    «применимо, но не поставлено: 5» неправдой ещё 2026-09-08, и ответом стало поле covers,
    которое заполняется руками и потому в зрелом проекте не заполнено никем

  • vitals больше не засчитывает чужой хук за подключённый AQK. Проверялось ИМЯ в теле
    хука (/pre-commit|aqk/i), а слово «pre-commit» у хука фреймворка есть всегда: в живом
    проекте AQK не вызывался ни разу, а строка говорила «прописан в .git/hooks». Состояний
    теперь четыре — не знаем · хука нет · хук есть, но не наш · подключён, — и подключение
    считается обоими честными способами: прямым вызовом в теле и нашим хуком через
    .pre-commit-config.yaml. Как это делают снаружи: pre-commit узнаёт свой хук по маркеру в
    теле (is_our_script()), а не по имени

  • smoke.sh отказывается целиком, когда мерить нечем. В песочнице, запрещающей
    подпроцессам Node запускать git и npm, прогон давал 15 «падений» из 123 — их не было.
    Человек час разбирал несуществующие дефекты. Теперь предполёт спрашивает того же, кого
    спросит прогон, и при отказе выходит кодом 3 — тем же, которым pytest отделяет внутреннюю
    ошибку от провала теста. Частичный прогон не печатается: 108 зелёных из 123 при недоступном
    git — это не «почти всё хорошо», а «мерить было нечем»

  • report и doctor --run не падают там, где нечего записать. В рабочей области, где
    .aqk/ не создать (read-only контейнер, чужой конвейер, каталог под ревью), команда падала
    с EROFS, не напечатав ни строки, — побочное действие отменяло то, ради чего её звали.
    Теперь результат печатается, а несохранение называется вслух: context и prompt читают
    отсутствие last-run.md как «прогона не было», и разницу надо видеть

  • Ложное срабатывание нашего же test-not-adjusted. Гейт краснел на ДОБАВЛЕННОМ
    комментарии: checkwash принимает строковый литерал "\n" за имя тестового юнита, и файл
    с двумя такими литералами на любом сдвиге строк получает TEST_DISABLED уровня high.
    Воспроизводится на чистом репозитории в шесть строк, в 0.2.13 и 0.3.4 одинаково. У себя
    обошли устранением настоящего повтора, но цена записи названа вслух в её README: тот же
    ложный приговор может прилететь любому проекту с обычным split("\n") в тестах

  • hook-actually-fires проверяет, что файл команды существует. Хук, указывающий в пустоту,
    не срабатывает никогда, а гейт с таким именем говорил «чисто». Граница узкая: красится только
    относительный путь со слэшем; программа из PATH (npx, bash -c …) не судится — у неё нет
    пути; абсолютный путь пропускается как относящийся к чужой машине

  • ci-actually-fails больше не обвиняет напрасно. Гашение красится, только если погашенная
    команда — последняя в блоке. pnpm eslint src > out.txt || true, а строкой ниже diff с
    эталоном — это законный уклад: линтер ОБЯЗАН выйти ненулевым, вердикт выносит следующая команда

  • entry-links-exist не красит рабочие ссылки. ../../releases — так сам GitHub предлагает
    ссылаться на выпуски, путь считается от адреса файла в вебе; строка запроса
    (assets/demo.gif?raw=1) больше не читается как часть имени файла

  • no-phantom-package не обвиняет подстановку. «Когда npm install @types/xxx не находит
    пакет типов» — это многоточие, сказанное словами, а не выдуманный пакет

Добавлено

  • requires: в манифесте проекта — чем работает гейт, когда по команде этого не видно.
    Гейт вида docker run … promtool test rules … заставлял vitals смотреть на первое слово и
    отвечать «инструменты на месте». Поле для этого существовало, но читалось только из
    <samples>/<гейт>/gate.yml — то есть было доступно нашим записям каталога и недоступно
    гейтам проекта, у которого samples пуст по построению. Соглашения снаружи нет и это сказано
    вслух: у pre-commit ровно эта просьба закрыта нерешённой (issue #2042), у lefthook такого
    ключа нет вовсе, — поэтому распространена своя форма, та же, что у covers: и groups:

  • AQK_GATE_TIMEOUT — предел времени гейта можно назвать своим. Пять минут были вписаны в
    четырёх местах, и способа решить иначе не было вовсе: живой проект, чей полный verify идёт
    дольше, просто не стал объявлять свою главную проверку гейтом. Умолчание не изменилось и не
    выдумано — столько же ждёт quality gate у SonarQube; переопределение переменной среды — тоже
    их способ и способ GitLab. Поля timeout у гейта в манифесте нет намеренно: его нет ни у
    pre-commit, ни у lefthook, а долгую проверку честнее объявить отдельной командой

  • Методичка operational-gates.md — карта эксплуатационных арбитров живого
    Django/Celery-проекта: OOM, N+1, топология очередей, реестр метрик, нагрузка и soak; что
    закрыто машиной, что только видно, и где граница. Шесть ссылок на первоисточники сверены
    запросом, а не по памяти

  • Первый запуск называет проверку, которая не может провалиться. doctor читал ИМЯ скрипта
    и печатал каноничную npm test с зелёной галочкой, ни разу не заглянув в его ТЕЛО, — а
    выключатель стоит именно там. На репозитории, где выключено всё (node --test || true,
    ruff … --exit-zero, "test": "echo todo"), первый экран говорил «у вас уже есть 2 проверки».
    Теперь такая проверка помечена крестом, причина названа дословно той строкой, которую человек
    найдёт у себя глазами, и её больше не предлагают вписать в манифест: объявленная проверка,
    которая не может покраснеть, превращает дыру в зелёную галочку, за которую ручается машина.
    То же знание ушло в блок для агента — иначе агент впишет её сам. Граница узкая и взята у гейта
    ci-actually-fails: || true в СЕРЕДИНЕ команды — идемпотентность вспомогательного шага, а не
    выключенная проверка

  • aqk feedback --send — отзыв уходит одной командой. Отправляет ваш gh, вашей учётной
    записью GitHub, комментарием в открытое обсуждение проекта. Без браузера, без формы, без
    регистрации. Без флага наружу не уходит ничего — и это утверждение держит машина
    (smoke/feedback-send.test.mjs, подделка gh через AQK_GH), а не обещание в документации:
    мутацией проверено, что безусловная отправка роняет проверку. Своя строка — feedback --send "ваш текст". Согласие живёт в самом флаге: агенту в умениях сказано показать текст человеку и
    спросить, а флаг самому не добавлять

  • Своя витрина плагинов. .claude-plugin/marketplace.json — репозиторий раздаёт плагин сам:
    /plugin marketplace add arsen-ask-lx/Agent_Quality_Kit и /plugin install aqk@agent-quality-kit
    работают без чьего-либо одобрения

  • Размер пакета сверяет машина. Обещанное в README число сравнивается с npm pack --dry-run,
    округлённо до десятой доли мегабайта. До этого оно врало трижды: «230 КБ» в коде и «574.1 kB»
    в обоих README при настоящих 692

npx agent-quality-k...
Read more

v0.15.0

Choose a tag to compare

@github-actions github-actions released this 14 Sep 08:09
570f722

Выпуск про одно: комплект перестал молчать о себе. Сломанная проверка больше не зеленеет при
--since — отказ прибора теперь отличается от находки о коде везде: в прогоне, в отчёте, в блоке
для агента и в пометках pull request. И появилась единственная плата, которую комплект просит:
один ответ автору — по делу, один раз на проект и с уже собранным письмом.

Что может выглядеть иначе после обновления: гейт, который не смог отработать, при --since
остаётся красным (раньше мог позеленеть) и называет причину словами; в .aqk/last-run.md у такого
появился свой знак ?, а блок для агента печатает его отдельной строкой; совещательный гейт
своим таймаутом больше не роняет прогон, но назван вслух; один раз на проект doctor или блок
для агента печатают строку с просьбой об отзыве — выключается AQK_FEEDBACK=0.

Добавлено

  • aqk feedback — единственная плата за комплект: один ответ автору. Команда собирает из
    последнего прогона и пробы короткий отчёт — версия, уровень, стек, что покраснело, чего
    комплект НЕ СМОГ проверить, какие классы брака здесь не ловит никто — и даёт предзаполненную
    ссылку на задачу. Без путей, без кода и без имени репозитория; человек видит глазами всё,
    что отправляет, и отправляет сам. Исходящих запросов у комплекта по-прежнему ровно один —
    про свежесть версии.

    Просьба об отзыве печатается один раз на проект и только когда есть что рассказать:
    «AQK не смог проверить X» (самое ценное), «проба нашла классы, которые здесь не ловит никто»,
    «комплект поймал вот это». Нечего рассказать — просьбы нет вовсе. Агенту она приходит в блоке
    context вместе с оговоркой «скажи один раз и не настаивай», человеку — строкой doctor.
    Выключатель — AQK_FEEDBACK=0.

    Почему: замер 2026-09-14 — 1342 скачивания в неделю в npm, но версии качаются равномерно,
    включая прожившую двадцать пять минут, то есть это зеркала и сканеры; на GitHub за две недели
    семь уникальных посетителей и ноль чужих комментариев за всё время. Просьба существовала, но
    печаталась при init — до того, как комплект сделал хоть что-то полезное

  • Третий знак в отчёте прогона: ? — «не смогли проверить». .aqk/last-run.md различает
    находку (✘) и отказ самой проверки (?), и блок для агента печатает их разными строками:
    гейт, который не сумел отработать, — не находка о коде, и агент, прочитавший его как находку,
    пойдёт чинить исправный файл. «Чисто» говорится только когда пусты оба списка

Изменено

  • Одно знание «мы это человеку уже показывали» вместо двух. Ограничитель обращений — совет,
    проверка версии, просьба об отзыве — сведён в tool/lib/ask.mjs: таблица видов объявляет, где
    лежит отметка (проект или дом) и через сколько можно повторить. Имена файлов прежние, поведение
    прежнее; связь с .gitignore теперь сторожит проверка — отметка, не названная в RUNTIME_FILES,
    уехала бы в чужой коммит
  • Формат отчёта прогона — в одном модуле. Писал его doctor, разбирал context — два файла,
    которые друг о друге не знают, держали один формат. Теперь и запись, и разбор в lib/run.mjs

Исправлено

  • Сломанная проверка больше не зеленеет при --since. Сужение до дифа шло по путям в выводе
    гейта — и под него попадал не только чужой старый долг, но и гейт, который НЕ СМОГ отработать:
    нет инструмента, неожиданный код, убит сигналом. Такой гейт называет в жалобе какой-нибудь путь;
    если путь не в дифе, строк не оставалось и прогон печатал зелёную галочку. Теперь исход запуска
    определяется ДО разбора вывода — тем же classify/findingCodes, что уже считают prove
    (у vulture находка это 3, у pylint битовая маска, у незнакомой команды только 1): сужать дифом
    можно находку, у сбоя места в коде нет. Строка прогона называет причину словами — «не смогли
    проверить: код 2 — у этой команды это сбой, а не находка» — и показывает первые строки жалобы
    инструмента. Совещательный гейт своим сбоем прогон по-прежнему не роняет, но назван вслух:
    раньше на таймауте ронял. В pull request сбой даёт общую пометку гейта, а не пометку у строки
    невиновного файла. Параллельный прогон (--jobs) терял signal и объяснил бы то же событие
    иначе — поправлено. Найдено внешним разбором соседнего инструмента (аудит Runcap, 2026-09-13):
    свои девяносто проверок знали этот класс отказа и проверяли его в гейтах, но не на дороге через
    флаг сужения
npx agent-quality-kit doctor

v0.14.0

Choose a tag to compare

@github-actions github-actions released this 11 Sep 12:15
78be90a

Выпуск про одно: от диагноза — к действию. aqk prompt пишет агенту готовое задание с
командой-арбитром у каждого пункта; находки гейтов видны пометками прямо в pull request; learn
показывает, что вам приходится повторять агенту, — прежде всего правило, которое уже записано и
всё равно не держится. Закрыт остаток отзыва с живого проекта: договор API в коде, язык вывода
по своду, «чего уровень не доказывает», короткий doctor. Новая запись каталога
entry-commands-exist — команды из свода существуют (9 из 99 публичных репозиториев с AGENTS.md
велят скрипт, которого нет).

Что может выглядеть иначе после обновления: doctor по умолчанию короче — пройденное и
неприменимое свёрнуты в строку, поимённо по --verbose или AQK_VERBOSE=1; без поля lang: язык
вывода берётся из AGENTS.md/CLAUDE.md/README.md, а не из локали машины; в GitHub Actions
упавшие гейты печатают строки ::error/::warning — это пометки для pull request, вердикт от них
не меняется; под уровнем от AQK-1 — две строки о том, чего он не доказывает.

Добавлено

  • Самопроверка на наборе настоящих случаев (tool/selfcheck/smoke/corpus.test.mjs). Десять
    минимальных воспроизведений того, что мы видели на живых проектах, в журнале и в разборах
    соседей — у каждого назван источник и записан ожидаемый ответ: близнецы с настоящими и
    поддельными воротами, свод с удалённым скриптом, договор в коде с tsc и без, CLAUDE.md с
    windows-переносами, русский свод без LANG, определения записей, разложенные в проект. На
    каждом случае все 24 переносимые записи обязаны ответить «чисто» или «находка», а не «не
    смогли». Семь секунд; три нарочно испорченных ожидания — три красных

  • Находки гейтов — пометками прямо в pull request. В GitHub Actions упавший гейт, чья
    находка называет файл, даёт красную пометку у этой строки дифа вместе со своим «почини: …»;
    совещательный — жёлтую; находка без файла — общую пометку гейта. Не больше десяти каждого вида
    за прогон, остаток — числом в логе. Формат сверен с документацией GitHub, экранирование — с
    официальным @actions/core. Идея — из разбора AgentLint, у которого пометки есть, но на
    близнецах их проверки одинаковы для рабочих и нерабочих ворот

  • learn показывает, что вам пришлось повторять. Реплики, где вы сами сказали «я же
    говорил», «опять», «снова», идут первым блоком; такая реплика, совпавшая с правилом свода, —
    отдельно: «записано, а поправлять всё равно приходится», правилу нужен сторож. Идея — из разбора
    AgentLint (их SS2 сопоставляет поправки с правилами по словам). Замер на логах владельца
    отверг их способ: из 45 поправок к записанным правилам относятся от силы две. Пометка повтора
    самим человеком оказалась надёжнее: на двух проектах 8 таких реплик, настоящих норм 7, а
    прежний отбор по словам «всегда»/«никогда» не ловил ни одной. «Опять» в вопросе («че опять
    rust?») — недоумение, а не норма, и не считается

  • aqk prompt — одно задание для агента. Между диагнозом и действием не было моста:
    doctor пишет человеку, context говорит агенту «как дела», а «почини вот это» человек
    пересказывал сам. Теперь сверху — правила поведения (команды не выдумывать, чинить код, а не
    проверку, решения владельца — спрашивать), дальше до пяти пунктов по весу: красные гейты, брак,
    подсаженный пробой и не пойманный, свои проверки проекта, свод, невидимый Claude Code, записи
    каталога — эти как предложение владельцу, а не приказ. У каждого пункта — команда, которая
    докажет «готово». Прогона не было или он устарел — первым пунктом «прогони», а не пустое
    «всё чисто». Идея из разбора agentlint; их «проверь» — «балл вырос», у нас — команда-арбитр

  • Запись entry-commands-exist: команды из свода существуют в проекте. Агент берёт команды
    из свода дословно; скрипт удалили — свод продолжает велеть «npm run lint:cli». Замер на 99
    публичных репозиториях с AGENTS.md: в 9 свод называет скрипт, которого нет ни в одном
    package.json; в двух история показывает механизм — скрипт удалён, строка в своде осталась.
    Сверяются npm|pnpm|yarn|bun run X (блок "scripts" всех package.json), make X (цели всех
    Makefile), just X (justfile). make и just — только внутри кода: «make sure» не
    команда. У соседа, agentlint, то же правило знает только npm — на живом проекте с шестнадцатью
    целями make в своде оно молчит по построению

  • doctor называет свод, которого не видит Claude Code. Документация Claude Code: «reads
    CLAUDE.md, not AGENTS.md». Проект с .claude/ и сводом только в AGENTS.md — или с
    CLAUDE.md, который AGENTS.md не подключает, — получает строку с готовой починкой:
    @AGENTS.md в CLAUDE.md. Где Claude Code не настроен, строки нет: Codex и Cursor читают
    AGENTS.md сами

Исправлено

  • Договор API в коде больше не невидим. Отзыв с живого проекта: схемы zod в общем пакете,
    сервер на @fastify/type-provider-zod — а doctor писал «спецификации API не видно»,
    потому что знал договор только по имени файла openapi*. Теперь договором считается и
    зависимость в package.json: tRPC, ts-rest, @hono/zod-openapi, провайдеры типов Fastify.
    Арбитр такого договора — проверка типов; api-contract-has-arbiter краснеет, если tsc
    (vue-tsc, tsgo) не запускает ни одна команда. Один zod договором не считается.
    На том же проекте запись теперь применима и зелёная: tsc --build стоит в scripts
  • Язык вывода — по языку проекта, а не машины. Отзыв с живого проекта: свод и методички на
    русском, Windows без LANG — весь вывод английский, пока не впишешь lang: руками. Теперь
    без поля lang: язык берётся из прозы AGENTS.md, CLAUDE.md и README.md (код, пути и
    адреса не считаются), и только если текст молчит — из локали. AQK_LANG и lang: сильнее
  • Под уровнем стоит, чего он не доказывает. Отзыв с живого проекта: «AQK-3, All levels
    reached» при конвейере, который ни разу не запускался. Ступени меряют оснащённость — гейты
    показаны на образцах каталога; про файлы проекта знает только проба. Теперь при уровне от
    AQK-1 doctor пишет две строки: что проба знает о браке в ваших файлах (не запускалась · не
    поймала такие-то классы · поймала все подсаженные) и что прохождение конвейера отсюда не
    видно. Проба записывает в отметку, сколько классов поймано и у скольких поимка не доказана.
    Планку ступеней не подняли: отметка пробы в .gitignore, в конвейере её нет — «AQK-2 только
    после пробы» уронило бы уровень и badge --check у всех разом
  • doctor короче по умолчанию, поимённо — по --verbose. Отзыв с живого проекта: сто
    строк вывода, большая часть — зелёные галочки, и красное теряется между ними. Теперь прошедшие
    гейты, записи, которые держит машина, и неприменимые сворачиваются в строку со счётом;
    упавший, совещательный, совет и «что поставить» видны всегда. На этом репозитории без --run
    — 49 строк вместо 75, под --run тридцать зелёных строк становятся одной. В конвейере —
    AQK_VERBOSE=1
npx agent-quality-kit doctor

v0.13.0

Choose a tag to compare

@github-actions github-actions released this 11 Sep 09:03
6ba3615

Выпуск про одно: всё, что кит печатает зелёным, доказано — отзыв с живого проекта на
TypeScript и Biome нашёл места, где это было не так. Проба больше не засчитывает поимку, когда
гейт упал по своей причине; заявка covers: сверяется правилами того линтера, которым закрыт
гейт, — Biome и eslint, а не только ruff; неустановленная запись — ○, а не красный крест.

И то, что нужно проекту, где проверок больше тридцати: группы и --only / --skip для гейтов,
которым нужен стенд, --jobs N для параллельного прогона, служебные файлы .aqk/ сами уходят
в .gitignore. Новая запись env-secrets-not-committed — пароли в .env, которых не видит ни
один сканер секретов; её доказательство — случаи из журнала, а не придуманный образец.

Что может выглядеть иначе после обновления: init дописывает строки в .gitignore;
отсутствие .aqk/docs и .aqk/rules больше не роняет прогон; внутри конвейера (CI=true)
проба сама не запускается — ставьте её отдельной задачей.

Исправлено

  • Проба засчитывает «поймано» только по делу. Раньше «гейт покраснел после подсадки» и
    «гейт поймал брак» были одним и тем же: код возврата сравнивался, вывод выбрасывался. Отзыв с
    живого проекта на TypeScript и Biome: класс «цвет из токена темы» отмечен пойманным линтером,
    хотя Biome цвета не проверяет, — подсаженный кусок ломал форматирование. Итог «каждый класс
    кем-то ловится» был ложной уверенностью. Теперь поимка подтверждается ПАРОЙ, тем же приёмом,
    каким мы проверяем чужие гейты: гейт обязан назвать подсаженный файл и промолчать на ЗЕЛЁНОМ
    образце той же записи в том же месте. Краснеет и на зелёном — «падает от самой подсадки»;
    файла не назвал — «упал по своей причине»; оба — «поимка не доказана», а не «поймано».
    Воспроизведено на проекте с biome check .: старая проба — «ловит: lint», новая — «покраснело:
    lint (краснеет и на зелёном образце) — поимка не доказана»; настоящая поимка осталась поимкой
  • Заявка covers: сверяется правилами ТОГО линтера, которым закрыт гейт. Раньше коды ruff
    (T20, C901, BLE) искались в любом конфиге, и в проекте на Biome заявка «lint держит
    no-print-in-prod» была «не подтверждена» всегда — хотя noConsole стоял. Теперь линтер гейта
    узнаётся по команде, по npm-скрипту, который она зовёт, или по единственному конфигу линтера;
    правила берутся на его языке: ruff — коды из рецепта, eslint — имена правил из рецепта,
    Biome — новое поле записи biome_rules (имена сверены по схеме конфигурации Biome 2.5.12).
    Исходов стало три: «не подтверждена»; «неверна — у линтера нет такого правила» (у Biome нет
    правила под TODO); «проверить не умею» — тускло, а не обвинением. На живом проекте с Biome
    три ложных «не подтверждена» ушли
  • Проба сама не запускается внутри doctor --run в конвейере. Раз в сто коммитов она
    добавляла 2–3 минуты в случайный прогон CI. Теперь в конвейере (CI, GITHUB_ACTIONS, …)
    печатается одна строка — когда проба подошла по сроку — с советом поставить её отдельной
    задачей; AQK_PROBE=1 включает прежнее поведение. У человека проба по-прежнему идёт сама
  • vitals спрашивает npm view, если прямой запрос к реестру не прошёл. fetch в Node не
    знает прокси и зеркала из .npmrc, и vitals писал «не достучался до реестра» там, где
    npm view работал
  • В aqk help у vitals было undefined вместо описания. Исправлено, и заведён сторож:
    у каждой команды справки обязано быть описание на обоих языках
  • Проба больше не пишет «рабочее дерево не трогается», записывая .aqk/last-probe.md.
    Теперь: «файлы проекта не меняются; итог пробы пишется в .aqk/last-probe.md»

Добавлено

  • doctor --run --jobs N — независимые гейты параллельно. 34 гейта у живого проекта шли друг
    за другом больше минуты, «а быструю проверку, которую долго ждать, перестают запускать». На этом
    репозитории 30 гейтов: около 110 с по одному, 68 с с --jobs 3. По умолчанию выключено: гейты,
    пишущие в одни файлы, вместе падали бы через раз. Каждый гейт выполняется в рабочем потоке тем
    же spawnSync с тем же таймаутом, что и раньше; вывод — в порядке объявления

  • Группы гейтов и doctor --run --only / --skip. Отзыв с живого проекта: гейт цены меряет
    план на засеянной базе — объявишь, и он валит прогон без стенда; уберёшь, и promise-has-gate
    справедливо ругается. Прогон бывал только «всё или ничего». Теперь groups: { stack: [cost] }
    в манифесте и --skip stack в быстром прогоне; принимаются и группы, и имена гейтов.
    Пропущенные названы в выводе и в .aqk/last-run.md строкой «~ не запускался» — блок для
    агента читает их как «неизвестно», а не как зелёные. Неизвестное имя — отказ с причиной

  • Совет — на языке линтера проекта. «Начните с трёх» и находки пробы советовали eslint
    проекту на Biome: комплект читал package.json и Makefile, но не biome.json. Теперь при
    biome.json в корне команда даётся для Biome — одно правило разово:
    npx @biomejs/biome lint --error-on-warnings --only=suspicious/noConsole .. Флаг
    --error-on-warnings обязателен: правило вне рекомендованных Biome ставит на
    «предупреждение», и без флага команда выходила с нулём, напечатав находку. Имена правил и
    поведение проверены на Biome 2.5.12

  • Запись env-secrets-not-committed: пароли из .env не лежат в git. Замер: на
    закоммиченном .env пароль, придуманный человеком (Sup3rS3cret2024), не видят ни наш
    secrets-not-in-code, ни gitleaks 8.30.1 — у него нет ни формата, ни энтропии; .env.local
    не видит даже detect-secrets. Два правила: .env.local/.env.*.local в git — всегда
    находка; остальные .env* — если внутри ключ-секрет с настоящим значением. Не «любой .env»:
    dotenv рекомендует коммитить зашифрованный dotenvx, Next.js — .env.test, в проектах на Vite
    коммитят публичные настройки. Значение секрета в вывод не печатается. Замер на 11 живых
    репозиториях (включая Vite с 16 закоммиченными .env) и на пяти с закоммиченным
    .env.production.local из поиска кода GitHub: гейт краснеет на всех пяти, четыре находки
    настоящие, два ложных срабатывания (фикстуры в tests/ и демо в playgrounds/) закрыты
    исключением. Запись зрелая: случай в журнале шишек

  • Блок для агента говорит, что делать дальше и когда какую команду запускать. Раньше
    context отвечал только «как дела»: уровень, красное, проба. Три первых шага doctor
    знал, а в контекст они не попадали; карта команд жила только в --full, в восьми тысячах
    токенов, где агент её пролистывал. Теперь в коротком блоке:

    • «Дальше» — до трёх шагов из того же расчёта, что у doctor: завести стандарт, если
      .aqk.yml нет; объявить проверки, которые у проекта уже есть; закрыть классы, которые
      проба подсадила и ваши проверки не поймали; «начните с трёх». У каждого — готовая команда
    • «Когда что» — правила «ситуация → команда»: перед коммитом (зависит от того, стоит ли
      хук), после правки проверки (aqk prove), метка арбитра в своде, «проверка мешает — не
      ослабляй, спроси владельца», «готово = aqk report --since main»

    Форма — по документации Claude Code: «чем конкретнее и короче инструкции, тем стабильнее
    Claude им следует»; «"Run npm test before committing" instead of "Test your changes"».
    Блок вырос с ≈375 до ≈500 токенов

Изменено

  • init дописывает служебные файлы .aqk/ в .gitignore. last-run.md, last-probe.md,
    advice-shown, update-checked — состояние машины, их переписывает каждый прогон. Отзыв с
    живого проекта: last-run.md однажды закоммитили, и каждый make check оставлял изменённый
    файл. Методички и правила в .aqk/ по-прежнему коммитятся. Для тех, кто поставил раньше,
    doctor называет служебный файл, который видит git, — с готовой командой git rm --cached
  • Неустановленная запись каталога — ○, а не ✘. Крест в зелёном прогоне глаз читает как
    провал, и через неделю человек перестаёт смотреть на красное вообще. ✘ теперь значит одно:
    упало или пропустило брак
  • Нет .aqk/docs или .aqk/rules — прогон не краснеет. Методички — пособие, проект вправе
    держать их где-то ещё; пункт показан как совет (○). Точка входа, .gitignore и .git
    остаются обязательными
  • Первый doctor показывает главное вверху. Раньше сначала шёл список всех записей по две
    строки на каждую (вторая — «поставить: aqk add …»), и на requests «у вас уже есть» и «начните с
    этих трёх» начинались со строки 84 из 102. Теперь порядок: что уже держит → что у вас уже есть →
    что проверки пропустили → начните с трёх → остальные записи по одной строке с одной общей
    подсказкой → неприменимое. Подсмотрено у agentlint: у них первыми идут пять главных исправлений
npx agent-quality-kit doctor

v0.12.0

Choose a tag to compare

@github-actions github-actions released this 11 Sep 05:33
8086480

Выпуск про одно: первый же запуск показывает, что у вас хорошо, что нет и с чего начать —
вместо двадцати одинаковых крестов и минуты пустого экрана. doctor видит проверки, которые у
проекта уже есть (у восьми живых python-проектов из восьми, а не у трёх), называет брак, который
ваши проверки пропустили в ваших же файлах, и предлагает три первых шага с готовой командой.

И одно исправление, ради которого выпуск не стал ждать недели: на Windows гейты больше не
уезжают в WSL
— отчёт с живого проекта, где make check краснел не из-за кода.

Добавлено

  • doctor показывает проверки, которые у проекта УЖЕ есть. Если гейтов в манифесте нет,
    он читает package.json (scripts test, lint, typecheck, check…) и Makefile и
    печатает их галочками с источником — и готовую строку для gates:. Раньше проект с eslint,
    mocha и конвейером видел «держит машина 0»: мы считали только свои записи. Предлагаем, а не
    вписываем — гейт в чужом манифесте без спроса был бы нашим решением в чужом файле
  • «Начните с этих трёх». Когда не закрыто больше трёх записей, doctor выбирает три: сперва
    те, что родились из настоящего отказа (есть запись в incidents/) и закрываются одной
    готовой командой под ваш язык. У каждой — команда, которую можно выполнить прямо сейчас, и
    адрес инструмента (ruff, eslint, gitleaks, vulture…), и слово про хук перед пушем
  • Python-проекты тоже видят свои проверки. Кроме package.json и Makefile читаются
    .pre-commit-config.yaml (одной командой pre-commit run --all-files, хуки названы
    поимённо), окружения-проверки tox из tox.ini и pyproject.toml (tox -e lint, style,
    typing — матрица версий не предлагается) и исполняемые scripts/test|check|lint. Замер на
    восьми живых проектах (requests, click, flask, httpx, black, fastapi, pydantic, rich): свои
    проверки видели три из восьми, теперь — все восемь. Шаги конвейера не читаются намеренно:
    uv run --locked --group … ${{ matrix.x }} работает только в том конвейере
  • doctor предостерегает находками пробы, ничего не запуская. Проба подсаживает брак в
    копию ваших самых чинимых файлов и знала, какой класс ваши проверки пропустили, — но в
    отметку писала одно число, и человек в doctor не видел ничего. Теперь отметка несёт имена
    классов и файлы, а doctor печатает их над «начните с этих трёх»: ✘ swallowed-error ← src/utils.py и команду, которой поймать прямо сейчас. Три случая не сливаются: гейт стоял и
    проба его гоняла — «стоит, но здесь не ловит»; гейт объявлен, но проба его не гоняла
    (поставлен позже или медленный) — «покажет следующая»; гейта нет — совет. Пробы не было —
    одна строка о том, что она сделает. Блок для агента (context) называет те же классы по
    имени
  • Поле tool: у записи каталога — адрес инструмента, которым она проверяет. В совете
    показывается адрес того инструмента, которым начинается команда: python-проекту — ruff, а не
    ruff и eslint
  • Строка «идёт» во время doctor --run. Пока гейт работает, видно, какой именно и какой по
    счёту: ⋯ smoke [2/10] идёт…; по завершении строка сменяется на ✔ или ✘. То же на секунды
    доказательства перед уровнем. Только в терминале: в пайп и в конвейер не пишется ни байта

Исправлено

  • Windows: гейты больше не уезжают в WSL. На Windows 10/11 в System32 лежит bash.exe —
    заглушка WSL, и в PATH она стоит раньше Git Bash (установщик Git по умолчанию кладёт туда
    только Git\cmd). Команда bash kit/gates/x/check.sh . запускалась в Linux-подсистеме с
    другими программами и путями, и прогон краснел не из-за кода. Теперь все пять мест запуска
    (прогон, доказательство, проба, храповик, why) идут через одну точку, которая берёт
    bash.exe рядом с git.exe; явный путь — AQK_BASH. vitals называет bash ненайденным,
    если есть только заглушка. Отчёт с живого проекта: «через Git Bash все проходят». На ту же
    ловушку наступали Claude Code и
    Archon
  • Плавающий отказ gates.sh («отклонено: 1 из 29»). printf … | grep -q при
    set -o pipefail: grep выходит на первом совпадении, printf получает SIGPIPE, конвейер
    возвращает 141 — и раздел README, который есть, объявлялся отсутствующим. Воспроизведено
    100 из 100 под нагрузкой; поиск переведён на here-string
  • Проба не называет класс слепым, если подсадка сломала гейт, который до неё работал.
    Сломанный гейт мог быть тем самым ловцом — вердикт «не смогли проверить», а не «никто не
    ловит». Найдено пробой на самом комплекте: образец лёг на место общей библиотеки
    kit/gates/_skip.sh, двенадцать гейтов вышли с кодом 2 — включая тот, что этот образец
    ловит, — и проба назвала класс слепым
npx agent-quality-kit doctor

v0.11.0

Choose a tag to compare

@github-actions github-actions released this 10 Sep 13:10
303245f

Выпуск про одно: проба впервые заработала на чужих проектах — и первым делом поймала нас
самих.
До него probe запускалась у одного репозитория из семи; замер на десяти живых
проектах (chalk, execa, axios, dependency-cruiser, express, requests, click, flask, httpx,
black — от 377 до 6494 коммитов, с установленными зависимостями и объявленными СОБСТВЕННЫМИ
командами каждого) показал, что механика была недостижима для настоящего кода.

Пока её чинили, вскрылись четыре места, где наши же проверки молча зеленели там, где не
могли работать
. Это тот самый класс, против которого написан весь стандарт.

Изменено — поведение, которое может покраснеть у вас

  • Гейт, читающий историю, без репозитория выходит с кодом 2, а не 0. Раньше
    commit-explains-itself и test-not-adjusted в каталоге без git отвечали «проверять нечего»
    и код 0 — то есть «не смогли посмотреть» было неотличимо от «проверено и чисто». Договор
    комплекта: 0 чисто, 1 находка, ВСЁ ОСТАЛЬНОЕ «не смогли». Если вы гоняете эти записи вне
    репозитория, прогон станет красным — и это правда, а не регресс
  • Рецепты ruff получили -q --output-format=concise, рецепты eslint —
    --no-config-lookup и исключение образцов.
    Причина в «Исправлено» ниже

Добавлено

  • Проба работает на любом проекте. Образец подсаживается в КОПИЮ ПРОЕКТА, гейт запускается
    в ней своей командой КАК ЕСТЬ — в неё больше ничего не подставляется. Раньше пробовать можно
    было только команды, кончающиеся каталогом; замер на семи чужих репозиториях: у шести из семи
    команды такие (xo, eslint lib/**/*.js, mocha --require…, pytest), и проба не
    запускалась вовсе. Способ не выдуман — так двадцать лет устроено мутационное тестирование:
    Stryker копирует проект во временный каталог, симлинкует node_modules и гоняет родную
    команду. Копируется РАБОЧЕЕ ДЕРЕВО, а не HEAD: комплект зовут из хука до коммита
  • Сухой прогон по чистой песочнице — без него «покраснел от подсадки» неотличимо от «был
    красным и до неё». Гейт, красный до подсадки, и гейт, позеленевший от неё, из суждения
    исключаются: засчитывать чужой долг за свою поимку нельзя
  • Проба видит JavaScript. Красные и зелёные образцы .js для шести записей; семьи
    расширений — образец .js годится файлам .mjs и .cjs. До этого в каталоге было 28
    записей и НОЛЬ образцов на .js, то есть проба была слепа к самому распространённому языку
    и к собственному коду комплекта
  • Цена пробы перестала расти файлами. Длительности берутся из сухого прогона, гейты идут от
    быстрых к медленным, на первом красном — ранний выход, слишком медленные исключаются и
    НАЗЫВАЮТСЯ ПОИМЁННО. Замер: 103 секунды вместо таймаута на 600
  • doctor называет ЧЕЛОВЕКУ, сколько обещаний не сторожит машина. Числа считались и
    печатались давно — но только в блоке context, который читает АГЕНТ. Единственный, кто
    обязан помнить о непроверяемом обещании, был единственным, кому о нём не сообщали. Найдено не
    нами: отчёт живого проекта

Исправлено

  • Проверка, которая не может работать, зеленела. Подмена общей библиотеки
    kit/gates/_skip.sh давала код 0: гейт печатал «command not found» и объявлял проект чистым.
    Библиотеку подключает КАЖДАЯ запись каталога — одним испорченным файлом гасился весь набор
    защит. Теперь библиотека ставит метку последней строкой (так ловится и обрыв файла на
    середине), и все двенадцать подключений её проверяют
  • Родной рецепт выдавал НАШИ ЖЕ красные образцы за находки пользователя. aqk add кладёт
    их в проект — без них prove ничего не докажет, — и они существуют, чтобы быть
    неправильными. ruff перешёл на многострочные блоки, а обход построчный и вырезать блок не
    может. Итог: поставил запись при установленном ruff — получил вечно красный конвейер на
    файлах, которые положили МЫ
  • Рецепты eslint не запускались вовсе. ESLint 9+ требует eslint.config.*; четыре записи
    каталога на javascript и typescript у пользователя молча падали с кодом 2. Исключение теперь
    на ВХОДЕ, а не фильтром вывода: ESLint 10 выкинул однострочные форматы из ядра, и подгонять
    фильтр под формат каждого инструмента — гонка, которую не выиграть
  • Проба выдавала «не проверено» за «чисто». Итог считался одним числом: исходов три, веток
    было две, и unknown молча падал в «поймано всё». Проба, где ЕДИНСТВЕННАЯ запись вернула
    «инструмент не установлен», печатала «каждый применимый класс кем-то ловится»
  • Проба врала о манифесте. При объявленных гейтах, которым некуда подставить каталог, она
    говорила «гейтов не объявлено, сначала aqk add» — и отправляла заводить то, что уже заведено
  • Проба завышала число втрое. Считала класс × файл: шесть классов на трёх горячих файлах
    превращались в «18 непокрытых». Считали события, а называли их сущностями — ровно тот приём,
    который ловим у других
  • complexity-limit был вдвое слеп к JavaScript. Мерил вложенность делением отступа на
    четыре, а в JS отступ — два пробела: шесть уровней давали «три» и проходили предел молча.
    Дефект был невидим, пока в каталоге не было ни одного образца на .js
  • §10 PROJECT.md утверждал, что соседи не про готовность к работе агентов. Неправда:
    Factory Agent Readiness (9 столпов, 5 ступеней, 100+ сигналов) и kodustech/agent-readiness
    (109 звёзд, 39 проверок) — ровно про неё. Соседи названы поимённо и с размером
  • Числа в обещаниях разошлись с фактом. Пакет: обещано «230 КБ» в трёх живых местах, на
    деле 574. Методички: «13 файлов, 4312 строк» против 14 и 4663

Границы, названные вслух

  • Обещание вне точки входа не проверяет НИЧТО, и стандарт об этом даже не сообщал.
    Расширять область нельзя дёшево: распознаватель ловит любой выделенный пункт списка и на
    связанных документах утонет в ложных срабатываниях
  • Свойства работающей системы — скорость, память, поведение под нагрузкой — чтением файлов
    не проверяются вовсе. Это граница замысла, а не пробел
  • Правило со сторожем-человеком не сторожит никто. В нашем собственном своде так помечено
    12 правил из 14
npx agent-quality-kit doctor

v0.10.1

Choose a tag to compare

@github-actions github-actions released this 09 Sep 19:55

Выпуск исправлений правильности. Все четыре дефекта — одно правило, разные лица:
«не знаем» обязано иметь собственное слово в выводе. Как только у него нет своей ветки,
оно молча приклеивается к соседней — и почти всегда к «всё хорошо». Каждый дефект подтверждён
опытом до правки и повторён после неё в чистой копии.

Исправлено

  • Сбой инструмента засчитывался как доказательство. prove считал находкой ЛЮБОЙ ненулевой
    код на красном образце. Опыт: гейт, который ВИСНЕТ на красном образце и молчит на зелёном,
    получал вердикт proven: 1, ok: true — то есть зависший гейт объявлялся ловящим брак, и это
    считало ступень AQK-2. Заведён tool/lib/execution.mjs: три исхода запуска — чисто, находка,
    сбой инструмента с названной причиной (таймаут, сигнал, ошибка запуска, неожиданный код).
    Знание о кодах живёт в адаптере рядом с инструментом, потому что общего правила нет:
    замер показал, что у vulture находка это 3, а 1 и 2 — ошибки; у pylint находка идёт
    битовой маской, а 32 означает ошибку вызова. Правило «1 находка, 2+ сбой» переврало бы обоих
    в обе стороны
  • Один доказанный гейт покрывал любое число недоказанных. Вердикт был
    broken === 0 && proven > 0. Теперь сбой арбитра отнимает ступень, а законная недоказуемость
    (нет образцов, нет программы на этой машине, стоит рецепт под другой язык) — нет: иначе
    уровень зависел бы от того, что установлено
  • Проверка защиты сама создавала себе доказательство. protection-not-removed при
    отсутствии снимка создавал его и выходил с нулём. Опыт: убрать гейт, удалить снимок и уйти
    вперёд так, чтобы удаление оказалось глубже выкладки конвейера, — свидетель (история git)
    слеп, и проверка записывала уже ослабленный набор новым эталоном. Храповик крутился назад.
    Теперь проверка только сравнивает; снимок пишет установка (aqk add); отсутствующий и
    отставший снимок — красное
  • Расписка за диф считала команду выводом. evidence брал пути из команды И вывода разом:
    молчащий гейт делал «названным» любой файл из строки запуска. Так «доказывалась» каждая правка
    самих проверок. Теперь «названо» — только вывод, а имена из команды дают «обойдено молча»,
    включая отдельный файл, который прежде падал в «никто не смотрел»
  • У пробы пять состояний, а веток было три. off (выключена в манифесте) и unknown
    (счётчик коммитов не взять либо непонятое значение поля) печатались как «в проверенных местах
    каждый применимый класс кто-то ловит». Блок состояния читает машина, и она приняла бы это за
    разрешение

Изменено

  • Комплект сам исполняет test-not-adjusted. Мы советовали записи, которых сами не держали.
    Замер развёл три случая: эту запись поставили (на нашем коде она проходит); swallowed-error
    на нашем коде чист, но требует eslint — отдельное решение; no-print-in-prod даёт 216
    находок, и все они наш собственный вывод в терминал — его же README называет этот класс ложным
npx agent-quality-kit doctor