Files
portal/lefthook.yml
T
Дмитрий 44f4e84f61 build(lefthook): wire 4 brain controllers — C1/C2/C3/C4 (Task C5)
pre-commit jobs 11-13:
- l1-watcher (WARN-only via || true; glob settings.json + Tooling)
- cross-ref-checker (WARN-only via || true; glob 5 normative files)
- observer-of-observer (always exit 0 by design)

post-commit job 14:
- status-md (regenerates docs/observer/STATUS.md + stages it for
  next commit; never fails commit via || true)

Both l1-watcher and cross-ref-checker are WARN-only initially because:
- l1-watcher surfaces 9 known pre-existing 'name@source' drifts
  (see commit 57098dc); strict mode pending alias resolution.
- cross-ref-checker surfaces noise from historical «наследие» entries
  in headers (see commit aeb81ab DWC); strict mode pending refinement.

observer-of-observer is warn-only by spec (no fail until C3 prune
threshold 54 weeks).

Verified via npx lefthook run pre-commit on staged lefthook.yml —
all 14 jobs evaluate cleanly: 9 skipped (glob mismatch), 5 ran
(including new observer-of-observer warn).

Per ADR-011 + plan Task C5.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 06:39:41 +03:00

224 lines
13 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# =============================================================================
# lefthook.yml — Лидерра (фаза 0)
# =============================================================================
# Документация: https://lefthook.dev
# Установка хуков: npx lefthook install
# Удаление хуков: npx lefthook uninstall
# Ручной pre-commit: npx lefthook run pre-commit
# Пропуск (один раз): LEFTHOOK=0 git commit -m "..."
#
# Принципы (Прил. Н §1):
# - Pre-commit для быстрых проверок: gitleaks, markdownlint, cspell, Stylelint
# - Pre-push для медленных: полный gitleaks по истории + lychee
# - Pa11y — только в CI (требует Chromium)
# =============================================================================
min_version: 2.0.0
# Pre-commit: проверки на staged-файлах перед каждым git commit
pre-commit:
parallel: false
jobs:
# 1. gitleaks — поиск ПДн / токенов / API-ключей в staged
# Правило §5.2 правил Claude. Блокирует коммит при находке.
- name: gitleaks
run: ./bin/gitleaks.exe protect --staged --config .gitleaks.toml --no-banner
fail_text: |
gitleaks нашёл потенциальные ПДн / токены / API-ключи в diff.
Если это маска / тестовое значение — добавь в allowlist .gitleaks.toml.
Если реальные данные — удали и используй маски (+7XXXXXXXXXX, ***@***).
# 2. markdownlint — стиль Markdown с авто-fix
- name: markdownlint
glob: "*.md"
# Вендоренные сторонние скилы .claude/skills/{mermaid,ccpm,data-scientist}/ — не линтуем (их .md
# не наши; markdownlint-cli2 игнорирует .markdownlintignore при явных путях).
exclude:
- ".claude/skills/mermaid/**"
- ".claude/skills/ccpm/**"
- ".claude/skills/data-scientist/**"
run: npx markdownlint-cli2 --fix {staged_files}
stage_fixed: true
fail_text: |
markdownlint нашёл проблемы, которые не исправляются автоматически.
Запусти `npm run lint:md:fix` или поправь руками.
# 3. cspell — орфография на staged .md
# --no-gitignore: staged-файлы по определению tracked; без флага cspell
# (useGitignore:true) игнорирует worktree-коммиты под gitignored .claude/worktrees/.
- name: cspell
glob: "*.md"
# Вендоренные сторонние скилы .claude/skills/{mermaid,ccpm,data-scientist}/ — не проверяем орфографию.
exclude:
- ".claude/skills/mermaid/**"
- ".claude/skills/ccpm/**"
- ".claude/skills/data-scientist/**"
run: npx cspell --no-progress --no-summary --no-gitignore {staged_files}
fail_text: |
cspell нашёл слова, отсутствующие в словаре.
Если это валидное слово проекта — добавь в cspell-words.txt.
Если опечатка — поправь.
# 4. Stylelint — стиль CSS в HTML-прототипах
- name: stylelint
glob: "*.html"
run: npx stylelint {staged_files}
fail_text: |
Stylelint нашёл проблемы в CSS прототипа.
Запусти `npx stylelint --fix <file>` где возможно.
# 5. Pint — code style PHP (фаза 1, Прил. Н #11). Авто-fix на staged .php в app/.
- name: pint
glob: "app/**/*.php"
root: "app/"
run: php vendor/bin/pint {staged_files}
stage_fixed: true
fail_text: |
Pint не смог отформатировать какие-то файлы (синтаксическая ошибка PHP?).
Запусти `cd app && composer pint` локально, посмотри вывод.
# 6. Larastan — статанализ PHP (фаза 1, Прил. Н #12). Полный анализ при любой правке
# *.php в app/ (точечный анализ только staged-файлов невозможен — phpstan нужен граф
# классов). Скорость: ~5-10 с на default scaffold + baseline 3.
- name: larastan
glob: "app/**/*.php"
root: "app/"
# cache-dir задан через tmpDir в app/phpstan.neon (Sprint 2 Phase A,
# O-perf-07 — ускорение инкрементальных прогонов).
run: php vendor/bin/phpstan analyse --no-progress --memory-limit=512M
fail_text: |
Larastan нашёл новые ошибки выше baseline.
Запусти `cd app && composer stan` локально и поправь.
Если ошибка ложная — обнови `app/phpstan-baseline.neon`
(см. feedback_environment.md п.25 — генерация baseline в 2 шага).
# 7. squawk — линтер миграций PostgreSQL (фаза 1, Прил. Н #15). Срабатывает только
# на staged *.sql (db/schema.sql и будущие raw-SQL-миграции). Конфиг .squawk.toml
# в корне отключает bootstrap-неприменимые правила и дизайнные предпочтения проекта.
- name: squawk
glob: "*.sql"
run: ./bin/squawk.exe {staged_files}
fail_text: |
squawk нашёл проблемы в SQL.
Конфиг — .squawk.toml в корне проекта.
Если правило неприменимо к bootstrap — добавь в excluded_rules в .squawk.toml.
Если это будущая миграция Laravel в app/database/migrations/ —
создай локальный .squawk.toml рядом с более строгими правилами.
pgFormatter (Прил. Н #16) — отдельно через `npm run format:sql:check`,
НЕ в pre-commit (стиль schema.sql ручной, авто-fix не применяется).
# 8. ESLint+Prettier+Vue — frontend стиль (фаза 2, Прил. Н #22). Lint-only
# на staged .ts/.vue в app/resources/js/. Полный type-check (vue-tsc) и Vitest —
# отдельно (медленно для pre-commit: ~3 сек на vue-tsc, ~3 сек на vitest).
# Запускать вручную: `cd app && npm run type-check && npm run test:vue`.
- name: eslint-vue
glob: "app/resources/js/**/*.{ts,vue}"
root: "app/"
run: npx eslint {staged_files}
fail_text: |
ESLint нашёл проблемы в Vue/TS-файлах.
Запусти `cd app && npm run lint:vue` локально и поправь.
Авто-форматирование: `cd app && npm run format`.
# 9. adr-judge — декларативная проверка ADR Enforcement-блоков (Прил. Н #36).
# Читает `## Enforcement` блоки docs/adr/ADR-*.md, применяет forbid_*/require_*
# правила к staged-дифу. Вендорен из adr-kit v0.13.1 (MIT) → tools/adr-judge.py;
# пере-вендорить после `/adr-kit:upgrade`. Без --llm → только regex, без вызова
# Claude API, нулевая стоимость (AK6). Без glob — adr-judge нужен весь staged-диф.
# `-X utf8` обязателен: stdin Python на Windows = cp1251; диф с кириллицей иначе
# ломается на surrogate → UnicodeEncodeError (crash, не ADR-violation).
- name: adr-judge
run: git diff --cached --unified=0 | python -X utf8 tools/adr-judge.py --diff - --adr-dir docs/adr/
fail_text: |
adr-judge: staged-изменение нарушает задокументированное архитектурное
решение (ADR). Смотри file:line выше и docs/adr/ADR-*.md.
Если ADR устарел — сначала обнови ADR (и его Enforcement-блок).
# 10. deptrac — архитектурный гейт направления зависимостей / границ слоёв
# (Прил. Н #43, architecture-tooling). Анализирует app/app/** по 13 слоям
# из app/deptrac.yaml. Первый прогон: 0 нарушений — кодовая база уже
# конформна, baseline-файл не нужен; job падает на НОВОМ дрейфе (Model→
# Service, Service→Http и т.п.). Без glob точечного анализа: deptrac строит
# граф классов, нужен весь app/. Чистый PHP, без LLM (AK6).
- name: deptrac
glob: "app/**/*.php"
root: "app/"
run: php vendor/bin/deptrac analyse --no-progress
fail_text: |
deptrac: staged-изменение нарушает направление зависимостей между
слоями (см. вывод выше и app/deptrac.yaml ruleset).
Если это осознанное архитектурное изменение — сначала обнови
app/deptrac.yaml (и при необходимости ADR-005), затем коммить.
# 11. l1-watcher — детектор settings.json ↔ Tooling Прил. Н drift
# (brain governance C1, ADR-011 spec §6.1). WARN-mode (|| true): 9 pre-existing
# drifts (frontend-design@claude-plugins-official + 8 ToB plugins) — известный
# naming-vocabulary mismatch (settings.json machine name vs Tooling human name).
# Strict mode после добавления tools/.l1-watcher-aliases.txt — follow-up.
- name: l1-watcher
glob: "{.claude/settings.json,docs/Tooling_v8_3.md}"
run: node tools/l1-watcher.mjs || true
fail_text: |
l1-watcher detected settings.json ↔ Tooling Прил. Н drift.
Run /claude-md-management:claude-md-improver to formalize plugin.
(Currently WARN-only per follow-up alias work.)
# 12. cross-ref-checker — version drift между нормативными файлами
# (brain governance C2, ADR-011 spec §6.2). WARN-mode (|| true): real-world
# surfaces noise от исторических «наследие» entries в headers нормативки —
# refinement (scope to §0 cross-refs marker) — follow-up.
- name: cross-ref-checker
glob: "{docs/Pravila_raboty_Claude_v1_1.md,docs/Tooling_v8_3.md,docs/Plugin_stack_rules_v1.md,CLAUDE.md,MEMORY.md}"
run: node tools/cross-ref-checker.mjs || true
fail_text: |
cross-ref-checker detected version drift in §0 cross-refs.
Update offending file.
(Currently WARN-only per follow-up refinement.)
# 13. observer-of-observer — счётчик чтений docs/observer/ + 54-week self-prune
# (brain governance C3, ADR-011 spec §6.3). Скрипт всегда exit 0 (warn-only by
# design). При observer infrastructure не используется >=54 недель — warn.
- name: observer-of-observer
run: node tools/observer-of-observer.mjs check
fail_text: |
observer-of-observer reports stale state.
Consider running /brain-retro or archiving docs/observer/.
# Post-commit: regenerate STATUS.md dashboard (informational, not gate)
post-commit:
parallel: false
jobs:
# 14. status-md generator — brain governance C4, ADR-011 spec §6.4. Rebuilds
# docs/observer/STATUS.md after each commit. Pure JS +execFileSync — Security
# Guidance #40 compliant. STATUS.md becomes staged for NEXT commit — owner
# reviews before persisting.
- name: status-md
run: node tools/status-md-generator.mjs && git add docs/observer/STATUS.md || true
fail_text: |
status-md regeneration failed.
# Pre-push: проверки перед git push (медленнее, но реже запускаются)
pre-push:
parallel: false
jobs:
# 5. Полный gitleaks-скан всей истории (не только staged)
- name: gitleaks-full-history
run: ./bin/gitleaks.exe detect --source . --no-banner --config .gitleaks.toml --redact
fail_text: |
gitleaks нашёл утечки в истории коммитов.
Перед push разберись с каждой находкой.
# 6. lychee — проверка ссылок в narrative-доках (.md). HTML-концепты в web/v8/
# и liderra_v8_handoff/concepts/ намеренно НЕ проверяются — там root-relative
# ссылки на будущие маршруты Vue+Vuetify (/login, /register, /legal/*).
- name: lychee-links
run: ./bin/lychee.exe --config .lychee.toml "docs/**/*.md" "db/**/*.md" "*.md"
fail_text: |
lychee нашёл битые ссылки в .md.
Запусти `npm run links` локально, поправь URL или добавь в `.lychee.toml` exclude.
# Подавить служебный вывод
skip_output:
- meta
- skips