llm-wiki 0.3.1: ошибки, которые называют себя

· 2 мин · BadRabbit

Сегодня вышли сразу два релиза llm-wiki: 0.3.0 и 0.3.1. Перед ними были два дня работы, полностью посвящённые не новым функциям, а честности системы.

0.3.1: ошибки, которые называют себя

Извлечение правил из книг работает в фоновом воркере. Раньше, если оно падало, в интерфейсе было видно только «не удалось». Почему — непонятно. Теперь:

  • воркер пишет в системный журнал диагностику, по которой видно, что именно сломалось;
  • упавшее извлечение можно перезапустить по явному запросу, а не загружать книгу заново.

Ещё одно важное исправление: если книга не помещается в контекст модели, это теперь «упёрлись в лимит», а не вердикт «правил тут нет».

0.3.0: честные тесты

Самое неприятное открытие недели: часть тестов не падала, когда ломался код, который они якобы проверяли. Они проверяли, что функция вызвалась, а не что она сделала правильную вещь. Я переписал их так, чтобы:

  • тесты wikisvc и агента падали при поломке контрактов (целитель, книги, MCP);
  • покрытие считалось по всему коду, включая парсеры документов и обе CLI, и порог был поднят до реального уровня;
  • инварианты безопасности были прибиты негативными тестами: проверяется не только то, что разрешено, но и что запрещённое действительно запрещено. Один такой тест сразу нашёл обход пути на клиенте, который теперь закрыт.

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

Мелочи, которые не мелочи

  • пустые и однословные «цитаты» больше не проходят как подтверждённые;
  • перевёрнутые и выходящие за пределы книги диапазоны глав отклоняются, а не роняют задачу;
  • сервис отказывается работать с базой, которую мигрировала более новая версия;
  • MCP-инструмент list_rules и отказ от необъявленных аргументов.

Доставка

Раньше сервер собирал всё сам. Теперь на каждый релиз публикуется один контейнерный образ, сервисы работают как контейнеры podman этого образа, а хост-часть ставится через nix build .#deployment: установщик, четыре systemd-юнита и llm-wiki-admin. Администратор может установить обновление прямо из интерфейса, а обновлятор предлагает только версии с тегом в main. В CI кешируется Nix store, так что сторонние пакеты собираются один раз.

Что я понял

Тест, который не может упасть, хуже отсутствия теста: он даёт уверенность, которой нет. Теперь у меня правило: написал тест — сломай код и убедись, что тест покраснел.