claude-harness/docs/HARNESS.md
2026-10-12 00:38:55 +04:00

99 lines
15 KiB
Markdown
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.

# Как работает обвязка
## Идея
Каждый инструмент отвечает за один вид памяти, и слои не пересекаются:
- **Gitea** помнит *что делать* между сессиями и неделями. Issue = фича, PR = точка человеческого контроля.
- **OpenSpec** помнит *как система должна себя вести*. `openspec/specs/` — текущее состояние, `openspec/changes/<id>/` — дельта текущей фичи. После merge дельта архивируется и вливается в specs.
- **Superpowers** ведёт *процесс внутри одной фичи*: brainstorming → writing-plans → subagent-driven-development → ревью → finishing-a-development-branch. Прогресс внутри плана живёт в ledger (`.superpowers/sdd/<plan>/progress.md`), который переживает компакцию и обрыв сессии, но удаляется после завершения.
- **codegraph** — карта кода для сабагентов: `codegraph_explore` вместо grep/Read по файлам. MCP-сервер привязан к папке запуска сессии (основной checkout); индекс worktree строится отдельно (`codegraph init` в worktree) и опрашивается через параметр `projectPath`.
- **Хуки** — то, что нельзя доверять промпту. Superpowers *просит*, хуки *запрещают*.
Клей между слоями — `global/CLAUDE.md`. Superpowers сам заявляет, что инструкции пользователя выше skills, поэтому вся маршрутизация живёт там.
## Цикл фичи
| # | Шаг | Кто | Артефакт |
|---|---|---|---|
| 1 | Формулируете цель одной фразой; агент заводит issue | вы + агент | issue #N |
| 2 | `brainstorming`: классификация spike / bounded / architectural, вопросы по одному, подходы, дизайн по частям | агент + вы | — |
| 3 | Спека в `openspec/changes/<id>/` (proposal, specs/*, design) + раздел «Decisions made without discussion»; **ваше утверждение** | агент, вы | change |
| 4 | `using-git-worktrees`: ветка `feat/N-slug` | агент | worktree |
| 5 | `writing-plans`: план с Global Constraints, Review Focus, полным кодом задач; Task 1 — тестовая инфраструктура; **ваше утверждение** | агент, вы | `docs/superpowers/plans/*.md` |
| 6 | SDD: контроллер (sonnet) → implementer на задачу (haiku/sonnet) → reviewer (sonnet) → fix loop до 5 раундов → ledger | агент автономно | коммиты, ledger |
| 7 | Финальное ревью всей ветки (opus), одна волна фиксов | агент | — |
| 8 | `finishing-a-development-branch`: PR в Gitea с «Rulings I made» | агент | PR |
| 9 | Ревью PR в Gitea; комментарии → `receiving-code-review` → правки в ветке; **вы делаете merge** | вы ↔ агент | merge |
| 10 | «Закрывай»: чеклист из 7 пунктов (см. CLAUDE.md) | агент | archive, closed issue, follow-up issue, чистый main |
Шаги 6–8 идут без остановок. Агент останавливается только на необратимой операции, вопросе безопасности, побочном эффекте вне worktree или плане, который невозможно исполнить.
**Bounded-задача** (флаг, фикс) идёт короче: дизайн в чате, файл `.bounded` в корне worktree (пропускает хук require-plan), TDD, коммит, PR. Без OpenSpec change и без плана.
## Subagent-driven development
Три роли, один цикл на задачу:
- **Контроллер** видит план, спеку, ledger и короткие статусы. Режет план на брифы (`task-brief`), запускает сабагентов, выносит рулинги, ведёт ledger. Кода не пишет. Запускается фоновым сабагентом на sonnet.
- **Implementer** — свежий сабагент на задачу. Видит только свой бриф и интерфейсы соседних задач. TDD, коммит, отчёт в файл, статус DONE / DONE_WITH_CONCERNS / NEEDS_CONTEXT / BLOCKED.
- **Reviewer** — свежий сабагент, получает бриф, отчёт и diff файлом (`review-package`). Два вердикта: соответствие спеке и качество.
Fix loop: раунды 1–3 продолжают того же implementer, 4–5 — свежий на более сильной модели. После пятого контроллер адьюдицирует сам и записывает рулинг. Minor-замечания в цикл не входят, откладываются до финального ревью.
Шаблоны сабагентов входят в superpowers: `implementer-prompt.md`, `task-reviewer-prompt.md`, `re-review-prompt.md`, `code-reviewer.md`. Это роли процесса, а не доменные специалисты; доменная экспертиза приходит через бриф с кодом, проектный CLAUDE.md и доменные skills.
## Решения без обсуждения
Единственное место, где видно, что агент решил за вас. Правило в CLAUDE.md: любое такое решение — на этапе спеки, плана или исполнения — пишется в `openspec/changes/<id>/design.md`, раздел `## Decisions made without discussion`, с датой, обоснованием и ценой ошибки. Ledger удаляется, чат теряется, design.md архивируется со спекой.
Читать: спеку один раз при утверждении, раздел решений каждый раз, когда он пополняется (после спеки, после плана, в финальном отчёте SDD). Каждое решение — вопрос «согласен ли я»: согласен — ничего не делать; не согласен — сказать агенту, он поправит; непонятно — спросить.
## Маркировка находок
Всё, что всплывает за фичу — замечания ревьюеров, рулинги контроллера, наблюдения, комментарии в PR — получает маркер источника и сохраняет его во всех документах: ledger → отчёт контроллера → PR → design.md → follow-up issue.
| Маркер | Источник | Пример |
|---|---|---|
| `T<n>.<k>` | minor из ревью задачи n плана | `T1.1` — Node-глобалы проходят проверку типов в `src/core` |
| `C-n` / `I-n` / `M-n` | финальное ревью ветки: critical / important / minor | `M-3` — жёсткий путь к vault в конфиге сборки |
| `R-n` | рулинг контроллера (процесс, план vs спека, состав фикс-волны); рядом номер решения в design.md | `R-5 (design #33)` — claimAll следует спеке, не плану |
| `O-n` | наблюдение контроллера вне ревью | `O-1` — счётчики в отчётах implementer неточны |
| `H-n` | комментарий человека в PR | `H-1` — переименовать поле |
Статус каждой находки — `fixed <commit>`, `deferred` или `rejected <причина>`; пункт без статуса в финальном отчёте контроллера считается ошибкой. Отложенное живёт не в ledger (он удаляется) и не в чате, а в одной issue Gitea `Follow-ups from #N`, которую агент заводит при закрытии. Следующая фича начинается с `tea issues ls` — и там эти пункты видны.
Зачем так: на пилоте контроллер придумал маркеры сам (T по номеру задачи без счётчика, P/F для рулингов), два пункта остались без маркера, а весь список отложенного жил только в удалённом ledger и в чате.
## Хуки
| Правило | Файл | Механизм |
|---|---|---|
| Никаких изменений на main / detached HEAD | `guard-main.sh`, PreToolUse на Edit/Write/MultiEdit/Bash | проверяет ветку; для Bash блокирует команды, похожие на запись (`>`, `tee`, `sed -i`, `mv`, `rm`, `git commit/push`…), пропускает `git worktree add`; коммит/push в main разрешены только если изменены исключительно файлы в `openspec/` (архивация) |
| Правки в коде только при плане или `.bounded` | `require-plan.sh`, PreToolUse на Edit/Write/MultiEdit | защищает любой `src/` на любой глубине (`api/src/`, `packages/*/src/`) или каталоги из `.claude/code-paths`; ищет план в `docs/superpowers/plans/` для текущей ветки или файл `.bounded` |
| Обвязка подключена к проекту | `harness-check.sh`, SessionStart | при старте сессии проверяет `openspec/`, `.codegraph/`, секцию в CLAUDE.md; если чего-то нет — пишет агенту инструкцию запустить `~/.claude/harness/adopt-project.sh` (спросив пользователя; `HARNESS_AUTO_ADOPT=1` — без вопроса) |
| Подсказка роли по заголовку сессии | `role-hint.sh`, SessionStart (все источники) | читает `session_title`; если начинается с `dev|admin|analyst|qa` — одна строка-подсказка вызвать `/role`; ничего не блокирует |
| Тесты зелёные перед коммитом | git pre-commit в проекте (не входит в пакет) | обычный git-хук с командой тестов |
Exit 2 блокирует вызов и показывает агенту stderr, поэтому агент сам делает то, что просит сообщение. Оба обхода, замеченные на пилоте (запись через `echo >` вместо Write; push через detached HEAD), закрыты.
## Дисциплина между сессиями
Новая сессия начинается с роли (`/role`), затем `tea issues ls` и `openspec list`, а не с памяти о прошлой. Незавершённый план возобновляется из ledger в worktree. Связка разваливается не на исполнении, а на закрытии — поэтому «закрывай» выполняет весь чеклист без остановок.
## Роли
Одна сессия — одна роль: `dev`, `admin`, `analyst`, `qa`. Роль даёт сессии только свои правила, свои файлы на старте и свой раздел памяти; процесс разработки (superpowers → Gitea → OpenSpec, SDD, чеклист закрытия) живёт в роли dev и не загружается в сессии admin.
Два слоя, оба в git: общий — `~/.claude/roles/<r>.md` (из пакета, `install.sh`), проектный — `<workspace>/.claude/roles/<r>.md` (для dev — файл, для остальных — симлинк в репозиторий направления `admin/`, `qa/`, `analysis/`). Формат одинаковый: четыре раздела «Процесс», «Читать на старте», «Не делать», «Делегировать»; при конфликте побеждает проектный слой.
Выбор роли, от автоматического к ручному: заголовок сессии (`claude -n "admin …"`; хук `role-hint.sh` печатает подсказку `[claude-harness] Роль сессии: admin`), вывод из первого сообщения (правило в глобальном CLAUDE.md: объявить «Роль: admin; если не так, скажи»), явно — `/role <r>`. Skill `/role` читает оба слоя, раздел памяти роли, строки «Читать на старте», а строки с префиксом `brief:` отдаёт фоновому агенту `briefing`, который возвращает выжимку: активные задачи, решения, открытые вопросы, ловушки.
Workspace из нескольких репозиториев (не git, cwd всех сессий) описывается таблицей `| Каталог | Репозиторий | Роль |` в его CLAUDE.md; `link-roles.sh` по ней создаёт симлинки на проектные файлы ролей и агентов направлений. Память агентов (`memory: project`) через симлинк каталога не работает (проверено 2026-10-11, спека, раздел 11), поэтому агентам направлений применяется запасной вариант спеки 6.5: поле `memory` не используется, промпт агента велит читать `<dir>/notes/agent-memory.md` при старте и дописывать в конце. `adopt-project.sh --workspace` и `new-project.sh --workspace --role …` собирают workspace из шаблонов; `doctor.sh` проверяет ссылки и размеры.
Политика памяти (глобальный CLAUDE.md): состояние задачи — в трекере; уроки, решения владельца и рецепты — в `notes/` направления и памяти агентов (в git); в локальной auto-memory — только ловушки машины и индекс со ссылками. При закрытии файл auto-memory задачи сворачивается в строку `registry-closed.md`.
## Стоимость
Bootstrap superpowers (~3 КБ) вставляется на каждом старте и после компакции. SDD стоит свежий контекст на задачу и на ревью; подробный план с готовым кодом позволяет отдать большинство задач haiku. Для планов до 5 задач дешевле `executing-plans` (Native): один контекст, одно ревью в конце.