claude-harness/CLAUDE.md

57 lines
14 KiB
Markdown
Raw Permalink 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.

# 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`.