claude-harness/CLAUDE.md

14 KiB
Raw Blame History

claude-harness

Что это

Пакет обвязки для разработки с Claude Code: глобальный CLAUDE.md с процессом, три блокирующих хука и неблокирующий role-hint, скрипты подключения проекта и skill диагностики. Для одного разработчика, который ведёт фичи через superpowers, хранит задачи в Gitea и требования в OpenSpec. Главный сценарий: bash install.sh ставит глобальную часть в ~/.claude, adopt-project.sh подключает существующий проект, new-project.sh создаёт новый; дальше проект живёт по docs/HARNESS.md. Репозиторий — источник; установленные копии в ~/.claude по месту не правятся.

Стек и ограничения

  • Bash (set -euo pipefail), markdown и python3 stdlib (3.8+). Логика guard-main и require-plan — hooks/harness_target.py, их .sh — обёртки; в остальных хуках и скриптах JSON разбирается встроенным python3. Других зависимостей времени выполнения нет. Внешние CLI (tea, openspec, codegraph) проверяются, но не требуются для установки.
  • Хук блокирует вызов только через exit 2 с сообщением в stderr; exit 0 — пропустить. Любой сбой разбора входа должен приводить к пропуску, не к блокировке.
  • install.sh идемпотентен: повторный запуск не ломает settings.json и делает бэкапы CLAUDE.md и settings.json с меткой времени. В settings.json он сливает hooks и только дописывает permissions.allow из global/permissions.json; чужие правила не трогает. Агент запускает его только с --no-permissions: права ставит владелец.
  • Хуки работают из ~/.claude/hooks/, пути в settings.hooks.json через $HOME; CLAUDE_CONFIG_DIR переопределяет ~/.claude.
  • macOS и Linux; python3 должен быть в PATH сессии Claude Code.

Архитектура

  • hooks/ — поведение обвязки, единственный «код» с логикой. guard-main.sh (PreToolUse на Edit/Write/MultiEdit/Bash): запрет записи в репозиторий на main/master/detached HEAD по цели записи (файл, цели команды Bash, git-мутации), без исключений. require-plan.sh (PreToolUse на Edit/Write/MultiEdit): правки в каталогах кода репозитория файла только при плане для ветки или файле .bounded. Обе — обёртки над harness_target.py: parse (команда → цели, без ФС) → resolve (путь → корень и ветка) → decide; режим targets — отладка разбора. harness-check.sh (SessionStart): проверка, что проект подключён. role-hint.sh (SessionStart, все источники): подсказка роли по session_title. settings.hooks.json — блок, который install.sh сливает в ~/.claude/settings.json.
  • install.sh, adopt-project.sh, new-project.sh — установка и бутстрап. install.sh копирует global/, hooks/, project-template/, adopt-project.sh, new-project.sh и skills/harness-doctor в ~/.claude/{CLAUDE.md,hooks,harness,skills}. adopt-project.sh работает на ветке chore/harness-init и вливает её ff в текущую ветку; это единственная разрешённая запись на main вне PR.
  • global/CLAUDE.md — глобальные правила процесса, ставятся в ~/.claude/CLAUDE.md. global/permissions.json — allow-правила цикла фичи (без merge и push в main), install.sh дописывает их в ~/.claude/settings.json и кладёт копию в ~/.claude/harness/ для doctor.sh. project-template/ — CLAUDE.md, CLAUDE.harness-section.md (секция «OpenSpec и superpowers», по ней harness-check узнаёт подключённый проект), ARCHITECTURE.md, gitignore.
  • skills/harness-doctor/ — skill диагностики: scripts/doctor.sh снимает состояние машины и проекта и прогоняет самотест хуков; SKILL.md — чеклист прочтения отчёта. fixtures/hook-cases.jsonl + scripts/hook_corpus.py — регрессионный корпус хуков (реальные команды с ожидаемым вердиктом, прогон в песочнице); лежит в skill, чтобы doctor.sh гонял его по установленным копиям.
  • roles/ — общий слой ролей (формат: четыре раздела, см. спеку ролей), skills/role/ — skill /role, agents/briefing.md — агент выжимки, link-roles.sh — симлинки workspace → репозитории направлений. Ставятся install.sh в ~/.claude/{roles,skills/role,agents,harness}.
  • tests/ — тесты пакета на bash: run.sh + test-*.sh, работают с источниками, install.sh ставят во временный CLAUDE_CONFIG_DIR.
  • caveman/config.json — выключенный по умолчанию caveman. examples/ — реальный CLAUDE.md проекта-пилота.
  • docs/HARNESS.md — как устроен цикл фичи, SDD, маркировка, закрытие. docs/PILOT-2026-09-27.md — пилот. docs/retro/ — ретроспективы, их метрики (<дата>.metrics.json) и скрипты: retro_metrics.py (срез метрик и поправки владельца), retro_leftovers.py (хвосты закрытия), hook_blocks_export.py и hook_cases_build.py (блокировки → корпус); проектный skill /harness-retro — .claude/skills/harness-retro/. docs/superpowers/specs/ — спеки фич обвязки, docs/superpowers/plans/ — планы.
  • Связь слоёв: хуки читают JSON вызова из stdin и состояние git проекта; скрипты бутстрапа читают project-template/; doctor.sh читает установленные копии в ~/.claude, не репозиторий.

Команды

  • bash tests/run.sh [имя] — весь набор тестов. Зелёным считается только весь набор.
  • bash install.sh --check — проверка окружения: бинарники, плагины, конфликты, allow-правила обвязки.
  • bash install.sh [--no-permissions] — установка глобальной части, идемпотентно; --no-permissions — без allow-правил.
  • bash skills/harness-doctor/scripts/doctor.sh [проект] — отчёт и самотест хуков. Только чтение.
  • bash adopt-project.sh <папка> [--no-merge] [--push] — подключить существующий проект. Из терминала, не из Claude Code.
  • bash new-project.sh <папка> [ssh-url] — каркас нового проекта.
  • /harness-retro <папка проекта> [--since ГГГГ-ММ-ДД] — ретро обвязки (в сессии в этом репозитории). Под ним: python3 docs/retro/scripts/retro_metrics.py <папка> [--since …] [--out …] [--markdown --prev …] [--corrections] — срез метрик; retro_leftovers.py <папка> [--fetch] [--markdown] — хвосты закрытия; hook_blocks_export.py [--since …] [--id-prefix …] <каталог> [...] — выгрузка блокировок в JSONL; hook_cases_build.py > skills/harness-doctor/fixtures/hook-cases.jsonl — сборка корпуса из разметки.
  • python3 skills/harness-doctor/scripts/hook_corpus.py hooks [--summary] — корпус хуков по источникам. python3 hooks/harness_target.py targets '<команда>' [cwd] — какие цели записи видит хук.

Тесты

  • tests/run.sh — автоматические тесты источников (хуки через фиктивный JSON, скрипты во временных каталогах, размеры). Самотест хуков в doctor.sh проверяет установленные копии; перед ним bash install.sh.
  • Ручная проверка хука: на main в любом репозитории попросить агента создать файл, ожидается BLOCKED.
  • Хуки: test-hook-parse — разбор команды на цели; test-hook-guard-main, test-hook-require-plan — сценарии спеки hook-guards в песочнице из настоящих репозиториев; test-hook-corpus — корпус реальных команд (assert на запись, корпус должен совпадать со сборкой hook_cases_build.py); test-hook-export — экстрактор. Ретро: test-retro-metrics (синтетические транскрипты), test-retro-leftovers (песочница репозиториев), test-retro-skill. Плюс role-hint и скрипты install.sh, doctor.sh, link-roles.sh.
  • Правишь разбор или вердикт — сначала случай в test-hook-parse/test-hook-guard-main; меняется ожидаемый вердикт реальной команды — разметка в hook_cases_build.py и пересборка корпуса.

Текущая работа

Бэклог обвязки — docs/retro/2026-10-11.md, раздел 4 (B1–B12), и docs/retro/2026-10-24.md, раздел 5 (B13–B17, принят владельцем 24.10.2026); решения владельца — раздел 5 и раздел 6 соответственно. Находки ретро маркируются RT-n.

  • Сделано: B5+B6 часть 1 — слой ролей (PR #4, 0.3.0). Часть 2 (awp-ca) — issue #2, отложенные находки — issue #5.
  • Сделано: B1+B2 и отмена исключения openspec-only для guard-main — хуки по цели записи и корпус хуков (issue #6, PR #12, 0.4.0), спека — openspec/specs/hook-guards/. Отложенные находки — issue #13.
  • Сделано: B3 — allow-правило git push origin --delete печатают adopt/new-project, проверяет doctor (issue #22, 0.4.2). B4 закрыт в #6 (решение владельца 1). B10 — workspace-хук awp-ca, в части 2 issue #2.
  • Сделано: allow-правила цикла фичи ставит install.sh (issue #24, 0.5.0; пересмотр решения владельца 2).
  • Сделано: worktree — EnterWorktree в <repo>/.claude/worktrees/<slug>, вход без подтверждения (issue #25, 0.5.1). Для awp-ca вопрос открыт в части 2 issue #2.
  • Сделано: B12 — /harness-retro: срез метрик, поправки владельца, хвосты закрытия, корпус по сегментам (issue #29, 0.6.0), спека — openspec/specs/harness-retro/.
  • Сделано: первое ретро /harness-retro — по cc-harness (issue #33, docs/retro/2026-10-24.md), находки RT-21…RT-25.
  • Дальше: B13 (поправки в записях с tool_result), B14 (советы по настройке — с проверкой по документации), B15 (рецепт команд в изолированной сессии), B16 (#31), B17 (ретро по awp-ca на той машине).

OpenSpec и superpowers

  • Вход в любую задачу — superpowers:brainstorming. Skills openspec-propose и openspec-explore сами по себе не запускать.
  • Когда brainstorming классифицировал задачу как architectural, структуру change создать через openspec new change <id> (или /opsx:propose <id>), а содержимое proposal.md, specs/ и design.md написать по итогам brainstorming. tasks.md из OpenSpec не заполнять — задачи живут в плане superpowers.
  • /opsx:apply не использовать: исполнение идёт через writing-plans и SDD/executing-plans.
  • openspec archive <id> — после merge PR, как часть чеклиста закрытия.
  • Хук require-plan защищает любой каталог src/ на любой глубине. Если код лежит иначе — перечислить каталоги (префиксы от корня, по одному в строке) в .claude/code-paths. В этом репозитории код — hooks/ и skills/, они перечислены в .claude/code-paths.