The Daily Newsstand · Free, Always
Wednesday, August 19, 2026

README врёт: как я сделал open‑source линтер, который сверяет документацию с реальным репозиторием

Translate

README редко ломается в один момент. Обычно документация постепенно перестаёт соответствовать проекту: переименовали команду, перенесли файл, удалили .env.example, поменяли package manager или Docker service, а инструкция осталась прежней.

В итоге новый пользователь копирует команду из README и получает ошибку, а разработчик узнаёт об устаревшей документации только после issue, сообщения коллеги или неудачного запуска CI. При этом сам Markdown может быть совершенно правильным — проблема в том, что описанные в нём факты больше не соответствуют реальному проекту.

Мне стало интересно, какую часть таких ошибок можно находить автоматически, не выполняя команды из документации и не отправляя исходный код во внешние сервисы. Так появился RealityLint — open‑source CLI, который статически сверяет проверяемые утверждения из документации с фактическим состоянием репозитория.

Например, README предлагает выполнить npm run dev, но в реальном package.json остался только скрипт start. Или инструкция говорит скопировать .env.example, хотя этот файл уже удалён. То же самое происходит с Python entry‑файлами, Make targets, относительными ссылками, версиями и package manager.

Главный принцип RealityLint простой: если утверждение можно доказать по локальным данным репозитория — проверяем. Если надёжного доказательства нет — не угадываем. Поэтому инструмент не пытается «понять весь README», а работает только с конкретными фактами, которые можно проверить детерминированно.

В версии RealityLint v0.5.0 — Project Truth проект заметно вырос. Теперь можно проверять не только основной README, но и документацию проекта целиком:

realitylint . --all-docs

Поддерживаются README*.md, документы внутри docs/, CONTRIBUTING.md и собственные glob‑шаблоны.

Сейчас RealityLint содержит правила RL000–RL022. Инструмент умеет проверять npm/yarn/pnpm/bun scripts, относительные ссылки и локальные пути, .env.example и .env.sample, соответствие package manager lock‑файлам, Python entry files, Make targets, версии проекта и заявления о лицензии.

В v0.5 появились и более серьёзные проверки. Например, RealityLint умеет анализировать Docker Compose. Если документация говорит:

docker compose up api

а в compose.yml существует только service web, инструмент сообщит о расхождении. Также проверяются env_file, profiles и документированные localhost‑порты. README может предлагать открыть localhost:9999, хотя Compose уже публикует 8080 — это тоже можно обнаружить статически, не запуская контейнеры.

Ещё одно направление — переменные окружения. Допустим, приложение использует:

os.getenv("DATABASE_URL")

README говорит настроить DATABASE_URL, но в .env.example этой переменной больше нет. RealityLint может сопоставлять явные упоминания переменных в документации, env templates и распространённые способы обращения к ним в исходном коде.

Добавилась поддержка Go и Rust. Для Go можно проверять локальные go run targets и сравнивать заявленную в документации версию с go.mod. Для Rust/Cargo проверяются manifest, binaries, features и MSRV.

При этом одно из основных ограничений проекта осталось неизменным: RealityLint никогда не выполняет команды, найденные в документации. README рассматривается как недоверенный ввод. Инструмент работает локально, не требует API‑ключа, не отправляет исходный код наружу и не использует LLM как источник истины. Если утверждение нельзя проверить достаточно надёжно, оно пропускается.

Для старых проектов появился baseline‑режим. Если RealityLint впервые подключается к большому репозиторию и сразу находит накопившиеся проблемы, необязательно исправлять всё перед включением CI. Можно сохранить текущее состояние:

realitylint . --all-docs --write-baseline

а затем отслеживать уже новые расхождения:

realitylint . --all-docs

Также появились .realitylint.toml, настройка severity отдельных правил, отключение ненужных проверок, inline ignore directives для намеренно неправильных примеров, pre‑commit integration и JUnit XML. Помимо этого поддерживаются text, JSON, Markdown и SARIF.

Установить RealityLint можно из PyPI:

pip install realitylint

Обычная проверка текущего проекта:

realitylint .

Проверка нескольких документов:

realitylint . --all-docs

Для CI можно указать порог:

realitylint . --fail-on error

RealityLint также доступен как GitHub Action:

- uses: voonterr/realitylint@v1
  with:
    fail-on: error

Смысл такого сценария в том, чтобы замечать устаревшую документацию в том же pull request, который её случайно сломал. README обычно не портят специально — он становится неправильным побочным эффектом обычного изменения кода, структуры каталогов или конфигурации.

На момент публикации актуальная версия — 0.5.0. Проект находится в Beta, поддерживает Python 3.10+, тестируется на Windows, Linux и macOS, содержит 91 автоматический тест, опубликован в PyPI и доступен как GitHub Action.

Для меня основная идея RealityLint в итоге оказалась довольно простой: документация — это тоже часть интерфейса проекта. Если код проверяется тестами, metadata — валидаторами, а конфигурация — линтерами, то хотя бы часть конкретных утверждений README тоже можно проверять автоматически.

Не весь естественный язык и не любое предложение. Но утверждения вроде «этот файл существует», «эта команда определена», «этот Docker service есть в Compose», “эта переменная присутствует в env template” или «этот Cargo feature существует» вполне можно сверять с реальностью.

Исходный код: https://github.com/voonterr/realitylint

PyPI: https://pypi.org/project/realitylint/

Проект открыт для issues и pull requests. Особенно интересно мнение тех, кто поддерживает open‑source или большие внутренние репозитории: какие виды устаревания документации встречаются у вас чаще всего и что из этого стоило бы проверять автоматически?

View the original on Хабр

KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.