llm-wiki 0.3.1: ошибки, которые называют себя
Сегодня вышли сразу два релиза 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, так что сторонние пакеты собираются один раз.
Что я понял
Тест, который не может упасть, хуже отсутствия теста: он даёт уверенность, которой нет. Теперь у меня правило: написал тест — сломай код и убедись, что тест покраснел.