# Как работает обвязка ## Идея Каждый инструмент отвечает за один вид памяти, и слои не пересекаются: - **Gitea** помнит *что делать* между сессиями и неделями. Issue = фича, PR = точка человеческого контроля. - **OpenSpec** помнит *как система должна себя вести*. `openspec/specs/` — текущее состояние, `openspec/changes//` — дельта текущей фичи. После merge дельта архивируется и вливается в specs. - **Superpowers** ведёт *процесс внутри одной фичи*: brainstorming → writing-plans → subagent-driven-development → ревью → finishing-a-development-branch. Прогресс внутри плана живёт в ledger (`.superpowers/sdd//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//` (proposal, specs/*, design) + раздел «Decisions made without discussion»; **ваше утверждение** | агент, вы | change | | 4 | `using-git-worktrees` → `EnterWorktree` с именем: `/.claude/worktrees/`, ветка `worktree-` → `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 | «Закрывай»: чеклист из 8 пунктов (`~/.claude/roles/dev.md`, «Завершение») | агент | archive отдельным PR, closed issue, удалённая ветка, follow-up issue, чистый main | Шаги 6–8 идут без остановок. Агент останавливается только на необратимой операции, вопросе безопасности, побочном эффекте вне worktree или плане, который невозможно исполнить. **Удаление ветки фичи (п. 4 закрытия).** `git push origin --delete <ветка>` из worktree фичи, затем `ExitWorktree` (keep) и из основного checkout `git worktree remove .claude/worktrees/` и `git branch -D <ветка>`. guard-main с 0.4.0 эту команду не блокирует, но её может отклонить классификатор auto mode. Поэтому нужно allow-правило `"Bash(git push origin --delete:*)"`. Его вместе с остальными правилами цикла фичи (`global/permissions.json`) ставит `bash install.sh` в `~/.claude/settings.json`. Запускаете его вы: агент себе права не выдаёт. Если обвязка стоит с `--no-permissions`, строку добавляете в `.claude/settings.json` проекта сами: её печатают `adopt-project.sh` и `new-project.sh`, а `doctor.sh` показывает, найдена ли она. **Подтверждения.** В обычном режиме Claude Code спрашивает подтверждение на всё, что не покрыто allow-правилами. В auto mode решает классификатор: он пропускает или запрещает, но вас не спрашивает. Allow-правила проверяются раньше него. Вход в worktree вне `/.claude/worktrees/` спрашивает подтверждение при любых правилах (Claude Code ≥ 2.1.206). Поэтому worktree живут внутри репозитория: `EnterWorktree` с именем создаёт и открывает их без вопроса. `.claude/worktrees/` стоит в `.gitignore`, иначе worktree попадут в `git status` и в индекс codegraph основного checkout. Хуки берут корень и ветку записи из самого worktree, не из основного checkout. **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//design.md`, раздел `## Decisions made without discussion`, с датой, обоснованием и ценой ошибки. Ledger удаляется, чат теряется, design.md архивируется со спекой. Читать: спеку один раз при утверждении, раздел решений каждый раз, когда он пополняется (после спеки, после плана, в финальном отчёте SDD). Каждое решение — вопрос «согласен ли я»: согласен — ничего не делать; не согласен — сказать агенту, он поправит; непонятно — спросить. ## Маркировка находок Всё, что всплывает за фичу — замечания ревьюеров, рулинги контроллера, наблюдения, комментарии в PR — получает маркер источника и сохраняет его во всех документах: ledger → отчёт контроллера → PR → design.md → follow-up issue. | Маркер | Источник | Пример | |---|---|---| | `T.` | 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 `, `deferred` или `rejected <причина>`; пункт без статуса в финальном отчёте контроллера считается ошибкой. Отложенное живёт не в ledger (он удаляется) и не в чате, а в одной issue Gitea `Follow-ups from #N`, которую агент заводит при закрытии. Следующая фича начинается с `tea issues ls` — и там эти пункты видны. Зачем так: на пилоте контроллер придумал маркеры сам (T по номеру задачи без счётчика, P/F для рулингов), два пункта остались без маркера, а весь список отложенного жил только в удалённом ledger и в чате. ## Хуки | Правило | Файл | Механизм | |---|---|---| | Никаких изменений на main / master / detached HEAD | `guard-main.sh` → `harness_target.py`, PreToolUse на Edit/Write/MultiEdit/Bash | решает по цели записи, а не по cwd. Цели: файл Edit/Write; в Bash — редиректы (кроме `/dev/null` и `N>&M`), `tee`, `rm`, `mv`, `cp`, `sed -i`, `npm install`, `openspec archive`… с учётом `cd` и `git -C`; git-мутации (`commit`, `add`, `merge`, `reset`…; `push` — только если пушит в main; `switch -c` в той же команде меняет ветку). Цель вне репозитория или в worktree на ветке — пропуск; неразрешимый путь (`$VAR`) — пропуск; git-мутация с неопределённым репозиторием — блок. Исключений нет: архив OpenSpec — отдельным PR | | Правки в коде только при плане или `.bounded` | `require-plan.sh` → `harness_target.py`, PreToolUse на Edit/Write/MultiEdit | по репозиторию правимого файла, а не по cwd: защищает любой `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, поэтому агент сам делает то, что просит сообщение. Сообщение начинается с `BLOCKED [guard-main]:` или `BLOCKED [require-plan]:` и называет цель, репозиторий и выход. Оба обхода, замеченные на пилоте (запись через `echo >` вместо Write; push через detached HEAD), закрыты. Регрессия хуков — корпус `skills/harness-doctor/fixtures/hook-cases.jsonl`: реальные команды из транскриптов пилота с ожидаемым вердиктом. По источникам — `bash tests/run.sh hook`, по установленным копиям — строка «корпус хуков» в `doctor.sh`. Корпус собирается из сырой выгрузки `docs/retro/scripts/hook_cases_build.py`; разметка — в этом скрипте. Разбор одной команды: `python3 ~/.claude/hooks/harness_target.py targets '<команда>' `. ## Дисциплина между сессиями Новая сессия начинается с роли (`/role`), затем `tea issues ls` и `openspec list`, а не с памяти о прошлой. Незавершённый план возобновляется из ledger в worktree. Связка разваливается не на исполнении, а на закрытии — поэтому «закрывай» выполняет весь чеклист без остановок. ## Роли Одна сессия — одна роль: `dev`, `admin`, `analyst`, `qa`. Роль даёт сессии только свои правила, свои файлы на старте и свой раздел памяти; процесс разработки (superpowers → Gitea → OpenSpec, SDD, чеклист закрытия) живёт в роли dev и не загружается в сессии admin. Два слоя, оба в git: общий — `~/.claude/roles/.md` (из пакета, `install.sh`), проектный — `/.claude/roles/.md` (для dev — файл, для остальных — симлинк в репозиторий направления `admin/`, `qa/`, `analysis/`). Формат одинаковый: четыре раздела «Процесс», «Читать на старте», «Не делать», «Делегировать»; при конфликте побеждает проектный слой. Выбор роли, от автоматического к ручному: заголовок сессии (`claude -n "admin …"`; хук `role-hint.sh` печатает подсказку `[claude-harness] Роль сессии: admin`), вывод из первого сообщения (правило в глобальном CLAUDE.md: объявить «Роль: admin; если не так, скажи»), явно — `/role `. Skill `/role` читает оба слоя, раздел памяти роли, строки «Читать на старте», а строки с префиксом `brief:` отдаёт фоновому агенту `briefing`, который возвращает выжимку: активные задачи, решения, открытые вопросы, ловушки. Workspace из нескольких репозиториев (не git, cwd всех сессий) описывается таблицей `| Каталог | Репозиторий | Роль |` в его CLAUDE.md; `link-roles.sh` по ней создаёт симлинки на проектные файлы ролей и агентов направлений. Память агентов (`memory: project`) через симлинк каталога не работает (проверено 2026-10-11, спека, раздел 11), поэтому агентам направлений применяется запасной вариант спеки 6.5: поле `memory` не используется, промпт агента велит читать `/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): один контекст, одно ревью в конце.