гейт коммита: пять машинных проверок встали в pre-commit

Проверки существовали и запускались руками — то есть тогда, когда о них
вспоминали. Каждая из них ловит ровно тот класс поломок, который не виден при
чтении: фронтматтер разбирает загрузчик скиллов, а не человек; копия правила
расходится с домом молча; диаграмма mermaid выглядит правдоподобно и падает на
рендере; ruff и pyrefly стерегут ноль внешних зависимостей, без которого
tasks.py и docs.py перестают работать в чужом проекте. Полагаться на память в
таком наборе — значит узнавать о поломке от того, кто скачал плагин.

Ставится lefthook (конфиг в lefthook.yml, `lefthook install` один раз на клон),
пять задач в parallel. Glob разводит две половины: правка одних скриптов не
платит за рендер диаграмм (~15 секунд), правка документов не гоняет линтеры.
Внутри своей половины проверяется весь репозиторий, а не изменённые файлы — и
расхождение копии, и находка ruff в соседнем файле это ровно тот случай, когда
правка сломала не себя.

Два свойства названы в README и в шапке конфига, чтобы не выяснялись отладкой.
Первое: судится рабочее дерево, а не индекс — скрипты написаны как обход
репозитория и про git add не знают, поэтому частичный коммит при грязном дереве
проверяется по тому, что на диске. Второе: обход разовый — LEFTHOOK=0, и он
законен ровно для случая, когда найденное нечем чинить прямо сейчас.

Заодно поправлена строка README про диаграммы: «поэтому он не в гейте, а в
руках того, кто правит диаграмму» — с этой правкой она перестала быть верной.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
av
2026-08-07 09:24:37 +03:00
co-authored by Claude Opus 5
parent 37394444e8
commit 5067bc2048
2 changed files with 85 additions and 2 deletions
+37 -2
View File
@@ -228,6 +228,7 @@ claude plugin uninstall <плагин>@av-dev-skills --scope project
<plugin>/agents/ charter'ы сабагентов
scripts/ проверки репозитория: копии, диаграммы, фронтматтеры
pyproject.toml линтеры скриптов, только для этого репозитория
lefthook.yml гейт коммита: проверки документов
```
## Проверка скриптов
@@ -315,11 +316,45 @@ uv run python scripts/diagrams.py # 0 рендерятся, 1 нет, 3 нет
```
Рендерит `mmdc` с PATH или `npx --yes @mermaid-js/mermaid-cli`; ни того ни
другого нет — код 3, а не молчаливый успех. Прогон занимает секунды на блок,
поэтому он не в гейте, а в руках того, кто правит диаграмму.
другого нет — код 3, а не молчаливый успех. Прогон занимает секунды на блок
это самая дорогая из трёх проверок, и в гейте коммита она стоит **под glob по
markdown**: правка одних скриптов проходит мгновенно.
Чего проверка **не** ловит — расхождение диаграммы с прозой вокруг неё. Дословного
соответствия между текстом и графом нет, сличать нечего, и держится это
правилом старшинства, записанным рядом с каждой диаграммой: **в конвейере ревью
старший граф** (он и есть алгоритм планировщика, проза его объясняет), **в
остальных местах старшая проза** (диаграмма там сводка).
## Гейт коммита
Все пять проверок стоят в `pre-commit` через [lefthook](https://lefthook.dev) —
конфиг в [lefthook.yml](lefthook.yml), ставится один раз на клон:
```
lefthook install # пишет .git/hooks/pre-commit
lefthook run pre-commit # прогнать руками, не коммитя
```
| Проверка | Когда идёт | Сколько |
| --- | --- | --- |
| фронтматтеры | правка `*.md` | миллисекунды |
| копии правил | правка `*.md` | миллисекунды |
| диаграммы | правка `*.md` | ~15 с на весь репозиторий |
| `ruff check .` | правка `*.py` | доли секунды |
| `pyrefly check` | правка `*.py` | доли секунды |
Glob разводит две половины: коммит, трогающий одни скрипты, не платит за рендер
диаграмм, а коммит в документы не гоняет линтеры. Внутри своей половины
проверяется **весь репозиторий**, а не изменённые файлы: и расхождение копии, и
находка ruff в соседнем файле — это ровно тот случай, когда правка сломала не
себя.
Два свойства, о которых стоит знать заранее:
- **судится рабочее дерево, а не индекс.** Скрипты обходят репозиторий целиком
и про `git add` не знают: частичный коммит при грязном дереве проверяется по
тому, что на диске. Это цена того, что проверки — обход, а не фильтр файлов, и
она принята: расхождение копий и битая диаграмма ловятся именно обходом;
- **обход разовый — `LEFTHOOK=0 git commit …`.** Он законен ровно для случая,
когда найденное нечем чинить прямо сейчас; молча пропущенная проверка — нет.