Описание всех автоматических качественных ворот (quality gates), которые работают в Forgeplan CI и в локальных хуках. Документ отвечает на четыре вопроса для каждого гейта: что проверяет, когда запускается, как запустить локально, как исправить частые ошибки.
Связанный документ:
docs/methodology/QUALITY-GATES.ru.mdописывает методологические ворота (Verification Gate, Adversarial Review, R_eff scoring). Этот документ — про CI/CD инфраструктуру, а не про методологию.
| Гейт | Триггер | Блокирует |
|---|---|---|
cargo fmt --check |
pre-commit hook + CI | коммит, PR merge |
cargo check / cargo clippy |
pre-commit hook + CI | коммит, PR merge |
cargo test |
CI (PR, push dev) | PR merge |
forgeplan health |
CI + pre-commit hook | PR merge |
forgeplan validate |
CI | PR merge |
| MCP tool count drift detector | CI (PR, push dev) | PR merge |
Hooks в .claude/hooks/ — локальная страховка до CI. CI-гейты в
.github/workflows/forgeplan-health.yml — окончательный барьер перед merge.
Назначение: проверяет, что исходный код Rust форматирован согласно rustfmt
(нет несохранённых diff'ов после автоформата).
Когда запускается:
pre-commit-fmt.sh— pre-commit hook. Запускаетcargo fmt --check; при наличии dirty diff — прерываетgit commitс объяснением.- CI — каждый PR к
devилиmain.
Файл хука: .claude/hooks/pre-commit-fmt.sh
Как запустить локально:
cargo fmt # auto-fix (применяет изменения)
cargo fmt -- --check # dry-run — показывает diff без изменений; exit 1 при driftКак исправить:
# Просто запустить форматтер
cargo fmt
# Убедиться что всё чисто
cargo fmt -- --check # должен выдать exit 0, пустой stdoutФорматирование — ОБЯЗАТЕЛЬНО перед каждым коммитом (CLAUDE.md §Rust coding rules п.3).
Хук .claude/hooks/pre-commit-fmt.sh блокирует коммит автоматически,
но полагаться только на хук нельзя — запускайте cargo fmt вручную в
конце каждой сессии работы с кодом.
Назначение: cargo check проверяет компилируемость без сборки бинарей.
cargo clippy добавляет lint-правила с -D warnings — при любом
предупреждении возвращает exit 1.
Когда запускается:
- Локально: после каждого изменения кода (рекомендуется в рабочем процессе).
- CI: каждый PR к
devилиmain.
Полная команда для CI:
cargo clippy --workspace --all-targets --features test-helpers -- -D warningsКак запустить локально:
cargo check --workspace # быстрая проверка
cargo clippy --workspace --all-targets -- -D warnings # полный lintКак исправить:
Большинство clippy-предупреждений исправляются автоматически:
cargo clippy --fix --workspace --allow-dirty --allow-stagedЕсли предупреждение нельзя исправить автоматически, и оно false-positive — добавьте точечное подавление в код с объяснением:
#[allow(clippy::too_many_arguments)] // Нет способа разбить без потери читаемости
pub fn complex_init(/* ... */) { /* ... */ }Не подавляйте clippy::all или warnings глобально — это маскирует
реальные проблемы. Rust 1.95 усилил часть lint'ов (CLAUDE.md §Rust coding rules п.3).
Назначение: запускает весь тестовый suite workspace. Провал хотя бы одного теста — exit 1.
Когда запускается:
- CI: каждый PR + push к
dev. - Локально: обязательно перед каждым коммитом (CLAUDE.md §Rust coding rules п.3).
Как запустить локально:
cargo test --workspace # базовый запуск
cargo test --workspace --features test-helpers # с test-helper escape-hatches
cargo test --workspace --features test-helpers -- --nocapture # verboseSmoke-тест из CLAUDE.md:
cargo fmt && cargo fmt -- --check && cargo check && cargo testЭта последовательность обязательна перед любым коммитом. Порядок важен: сначала fmt (иначе fmt-check упадёт на следующем шаге), потом check (раньше test — быстрее), потом test.
Как исправить: исправьте упавший тест. Если тест падает из-за изменения в коде — это сигнал, что реализация сломала ожидаемое поведение. Не меняйте тест, чтобы заставить его пройти, не разобравшись в причине.
Назначение: проверяет состояние workspace артефактов — нет ли orphan
артефактов (есть в DB, нет в файлах), blind spots (активные без evidence),
stale артефактов. В CI режиме (--ci --fail-on) возвращает exit 1
при превышении порогов.
Когда запускается:
.claude/hooks/pre-commit-health.sh— pre-commit hook (локально)..github/workflows/forgeplan-health.ymlstepHealth check— CI.
CI-команда:
forgeplan health --ci --fail-on "orphans=10,blind_spots=5"Пороги: orphans=10 (терпимо до 10 orphan'ов — lance rebuild может
отставать), blind_spots=5 (более 5 активных без evidence — методологический
долг, блокирует merge).
Как запустить локально:
forgeplan health # обзор состояния
forgeplan health --ci --fail-on "orphans=10,blind_spots=5" # полная CI-проверкаКак исправить:
Orphan артефакты (есть в файлах, нет в DB):
forgeplan scan-import # переиндексирует markdown → LanceDB
forgeplan health # проверить что orphans=0Blind spots (активные без evidence):
forgeplan health # смотрим список blind spots
# Для каждого blind spot:
forgeplan new evidence --for <ID> "Smoke evidence" # или полноценный EVID
forgeplan activate <EVID-ID>Stale артефакты (TTL истёк):
forgeplan stale # посмотреть список
forgeplan renew <ID> --reason "..." --until 2026-08-01
# или если устарели совсем:
forgeplan deprecate <ID> --reason "obsolete"Файл workflow: .github/workflows/forgeplan-health.yml
Назначение:
forgeplan validate <ID>— проверяет артефакт на соответствие схеме (MUST-секции, frontmatter, формат). Возвращает exit 1 при ошибках.forgeplan score <ID>— вычисляет R_eff (weakest-link). Не блокирует CI сам по себе, но используется в health check'е.forgeplan blocked— показывает артефакты, заблокированные из-за незакрытых зависимостей.forgeplan order— топологическая сортировка работы по зависимостям.
Когда запускается:
forgeplan validate --ci— в CI stepValidate artifacts(.github/workflows/forgeplan-health.yml).- Методологический smoke-тест из CLAUDE.md (после каждого спринта):
forgeplan validate PRD-XXX && forgeplan score PRD-XXX forgeplan blocked && forgeplan order
CI-команда:
forgeplan validate --ci # валидирует все артефакты; exit 1 при любой MUST-ошибкеКак запустить локально:
forgeplan validate PRD-001 # конкретный артефакт
forgeplan validate --ci # все артефакты разом
forgeplan score PRD-001 # R_eff score
forgeplan blocked # что заблокировано
forgeplan order # в каком порядке работатьКак исправить:
Validate выводит список MUST-секций, которых не хватает, или поля с неверным форматом. Исправьте указанные секции. Validator принимает алиасы (CLAUDE.md §Validator aliases):
## Problem=## Motivation=## Problem Statement## Goals=## Success Criteria- и др.
Если validate падает из-за правильно написанного артефакта, возможно использован нераспознанный алиас — добавьте стандартный заголовок или проверьте список алиасов в CLAUDE.md.
Файл workflow: .github/workflows/forgeplan-health.yml
Назначение: сравнивает фактическое число MCP-инструментов в исходном
коде (crates/forgeplan-mcp/src/server.rs) с числами в документации
(README, CLAUDE.md, website, docs). Если документация расходится с кодом —
exit 1 (CI failure).
Предыстория (PROB-050): в audit v0.28.0 внешний OpenAI-агент обнаружил
~18 мест в документации с устаревшими счётчиками MCP-инструментов
(несколько разных исторических значений против актуального count на момент
v0.28.0). Этот script предотвращает повторение: каждый PR, который
добавляет или удаляет MCP-инструмент, автоматически провалит CI, пока
документация не обновлена. Конкретные числа здесь намеренно не
закреплены — чтобы этот раздел сам не стал drift-мишенью; live-count
эмитит scripts/check-mcp-tool-count.sh.
Source of truth: количество async-функций с паттерном async fn forgeplan_*(
в crates/forgeplan-mcp/src/server.rs.
Файл скрипта: scripts/check-mcp-tool-count.sh
Когда запускается:
- CI step
MCP tool count drift checkв.github/workflows/forgeplan-health.yml. Запускается последним в цепочке health-gate шагов: fmt → build → reindex → health → validate → drift-check. - Не запускается как pre-commit hook (слишком медленно для каждого коммита); рекомендован для запуска как pre-push check или локально перед PR.
Что проверяет:
Скрипт ищет в следующих путях:
CLAUDE.mdREADME.mdTODO.mdwebsite/src/(все.md,.tsx,.astro,.mdx)docs/(все.md)
Паттерн: строки вида <N> MCP tools, <N> инструментов, <N> tools
(только числа ≥ 10, чтобы не ловить "3 tools cover..." и подобное).
Исключения из проверки:
CHANGELOGфайлы и строки — исторические числа сохраняются намеренно.- Строки с комментарием
# mcp-count-drift: ignore. - TODO.md строки с паттерном
Previous: v0.*.
Как запустить локально:
# Строгий режим (как в CI)
./scripts/check-mcp-tool-count.sh
# Warn-only (не прерывает работу, только показывает drift)
./scripts/check-mcp-tool-count.sh --warn
# Помощь
./scripts/check-mcp-tool-count.sh --helpТипичный вывод при успехе (конкретные числа меняются от релиза к
релизу — <ACTUAL> это live-count из
grep -c 'async fn forgeplan_' …/server.rs):
Actual MCP tool count (src): <ACTUAL>
No drift — all docs are consistent with src (<ACTUAL>).Типичный вывод при drift (<ACTUAL> ≠ <STALE>):
Actual MCP tool count (src): <ACTUAL>
Drift detected (3 lines):
DRIFT: README.md:42:...<STALE> MCP … (number=<STALE> context="<STALE> MCP …")
DRIFT: CLAUDE.md:28:...<STALE> MCP … (number=<STALE> context="<STALE> MCP …")
DRIFT: website/src/content/index.mdx:17:...<STALE> MCP …
Resolution: update each location to actual count (<ACTUAL>) OR add a
comment explaining why the historical number is preserved (e.g. CHANGELOG).Как исправить drift:
-
Выяснить фактическое число:
grep -cE 'async fn forgeplan_' crates/forgeplan-mcp/src/server.rs -
Обновить все указанные в drift-выводе места. Замените старое число на актуальное (то, что вернул
grepна шаге 1) — вCLAUDE.md,README.mdи т.д., где упомянут MCP tool count. -
Если число в конкретном месте — исторически правильное (например, release-notes-строка ссылается на счётчик предыдущей версии) и менять нельзя, добавьте drift-ignore комментарий в ту же самую строку где находится число:
... <!-- mcp-count-drift: ignore -->(маркер ОБЯЗАН быть на одной строке с числом —grep -vline-anchored). -
Перезапустить скрипт:
./scripts/check-mcp-tool-count.sh # должен вернуть exit 0 -
Если изменили CHANGELOG.md — регенерировать website mirror:
cd website && node scripts/copy-changelog.mjs
Правило для авторов инструментов: при добавлении нового MCP-инструмента
(async fn forgeplan_<name>) обязательно обновите счётчики в CLAUDE.md
## Current status и README.md до создания PR. Иначе CI упадёт на
drift-check step.
Хуки — локальная страховка, запускаются до git commit. Они не заменяют CI,
но позволяют поймать проблемы раньше.
| Файл хука | Что блокирует | Когда |
|---|---|---|
forge-safety-hook.sh |
Деструктивные команды (rm -rf /, cargo publish, DROP TABLE, git push --force) |
pre-tool-use в Claude Code |
pre-commit-fmt.sh |
Коммит, если cargo fmt --check показывает drift |
git pre-commit |
commit-test-check.sh |
Коммит, если в diff есть новая pub fn без теста |
git pre-commit |
pr-todo-check.sh |
Push, если в PR открыты незакрытые P0-задачи | git pre-push |
pre-commit-health.sh |
Коммит, если forgeplan health показывает критические проблемы |
git pre-commit |
Важно: хуки расположены в .claude/hooks/ (для Claude Code integration),
но не в стандартном .git/hooks/. Они активируются Claude Code средой
как PreToolUse хуки. Стандартные git pre-commit хуки работают независимо
(при наличии).
Подробный гайд: docs/operations/AGENT-HOOKS.ru.md
Правильный порядок перед коммитом/PR — критичен. Неправильный порядок маскирует ошибки и затрудняет их изоляцию:
Перед каждым коммитом:
1. cargo fmt # fix
2. cargo fmt -- --check # verify
3. cargo check --workspace # 0 warnings
4. cargo test --workspace # 0 failures
5. forgeplan health # нет критических blind spots
Перед PR (дополнительно):
6. cargo clippy --workspace --all-targets -- -D warnings # strict lint
7. forgeplan validate --ci # все артефакты pass
8. ./scripts/check-mcp-tool-count.sh # нет driftПолный smoke-тест из CLAUDE.md:
cargo fmt && cargo fmt -- --check && cargo check && cargo test
forgeplan init -y && forgeplan new prd "Smoke" && forgeplan validate PRD-XXX
forgeplan score PRD-XXX && forgeplan blocked && forgeplan order
forgeplan fpf ingest && forgeplan fpf search "trust"Файл: .github/workflows/forgeplan-health.yml
Триггер: PR к dev или main, при изменениях в .forgeplan/** или
crates/**.
Шаги (в порядке выполнения):
actions/checkout@v4— checkout кода- Установка системных зависимостей (
protobuf-compiler) dtolnay/rust-toolchain@stable— Rust toolchainSwatinem/rust-cache@v2— кэш Cargocargo build -p forgeplan— сборка CLI- Rebuild index —
forgeplan init -y+ копирование markdown +scan-import(воссоздаёт LanceDB из tracked markdown файлов) - Health check —
forgeplan health --ci --fail-on "orphans=10,blind_spots=5" - Validate artifacts —
forgeplan validate --ci - MCP tool count drift check —
./scripts/check-mcp-tool-count.sh
Каждый шаг — самостоятельный exit-code барьер. При провале шага 7 шаги 8 и 9 не запускаются (fail-fast поведение GitHub Actions).
# 1. Узнать текущий count
grep -cE 'async fn forgeplan_' crates/forgeplan-mcp/src/server.rs
# 2. Найти места, которые нужно обновить
./scripts/check-mcp-tool-count.sh --warn
# 3. Обновить каждое указанное место (CLAUDE.md, README.md, website/, docs/)
# 4. Если изменён CHANGELOG.md — регенерировать website
cd website && node scripts/copy-changelog.mjs
# 5. Проверить
./scripts/check-mcp-tool-count.sh # exit 0Причина: локальный LanceDB мог содержать устаревшие данные из предыдущих init-ов. CI всегда делает clean init + scan-import. Воспроизвести локально:
forgeplan export --output backup-$(date +%Y%m%d).json
cp -r .forgeplan .forgeplan-backup-$(date +%Y%m%d)
rm -rf .forgeplan && forgeplan init -y
# Скопировать tracked markdown обратно:
cp -r .forgeplan-backup-*/prds/ .forgeplan/
cp -r .forgeplan-backup-*/rfcs/ .forgeplan/
# ... и т.д.
forgeplan scan-import
forgeplan health --ci --fail-on "orphans=10,blind_spots=5"Проверить версию rustfmt:
rustfmt --version # должна совпадать с CI (stable)
cargo +stable fmt -- --checkЕсли версии разные — обновите toolchain:
rustup update stablescripts/check-mcp-tool-count.sh— drift detector (исходный код с inline комментариями).github/workflows/forgeplan-health.yml— полный CI workflowdocs/operations/AGENT-HOOKS.ru.md— подробный гайд по pre-commit hooksdocs/methodology/QUALITY-GATES.ru.md— методологические гейты (Verification Gate, R_eff, Adversarial Review)docs/methodology/release-workflow.md— pre-conditions checklist релиза (использует эти гейты)CLAUDE.md§Hooks enforcement — краткий reference table хуков