# Proposal: хуки решают по цели записи Issue: #6. Источники: ретро `docs/retro/2026-10-11.md` — B1, B2, решение владельца 1; находки RT-1, RT-2, RT-6, RT-7. ## Why guard-main решает по тексту команды и по cwd оболочки, а не по тому, куда идёт запись. По подсчёту ретро около трёх четвертей блокировок за период пилота ложные: `2>/dev/null` считается записью, `grep "npm i"` — установкой пакета, Edit файла памяти вне репозитория — записью в main, потому что cwd стоит на main-checkout (RT-1). Чужой `cd` останавливает фоновый SDD-контроллер (RT-2), отказ хука запускает каскад отказов классификатора auto mode (RT-7). Реальных нарушений main за тот же период — ноль, перехват по делу — единицы. Регрессионных тестов на реальных командах у хуков нет (RT-6), поэтому любая правка регулярного выражения проверяется только в бою. require-plan болен тем же: корень, ветку, план и `code-paths` он берёт от cwd, а не от репозитория правимого файла. ## What Changes - guard-main определяет цели записи — файлы и git-мутации — и решает по ветке репозитория каждой цели. cwd служит только базой для относительных путей. - Неразрешимая файловая цель пропускается; git-мутация с неопределённым репозиторием блокируется. - `git push` считается записью в main, только если он пушит в main; `push origin ` и `push origin --delete ` из main-checkout проходят. - **BREAKING:** исключение для openspec-only коммитов и для `openspec archive` на main удаляется (решение владельца 1: архив всегда отдельным PR). Правила процесса уже приведены к этому в 0.3.0 (`roles/dev.md`); меняется поведение хука. - `pip install` больше не блокируется (пишет в окружение, не в репозиторий); `npm/yarn/pnpm install` в репозитории на main — блокируется, как и раньше. - require-plan берёт корень, ветку, `.claude/code-paths`, `.bounded` и планы из репозитория правимого файла. - Сообщения блокировки получают стабильный префикс `BLOCKED [guard-main]:` / `BLOCKED [require-plan]:`, называют цель и выход. - Регрессионный корпус: 126 записей из транскриптов плюс живые случаи, каждая с ожидаемым вердиктом; прогон из `tests/run.sh` (источники) и из `doctor.sh` (установленные копии). - Экстрактор `hook_blocks_export.py` выгружает только настоящие ошибки хуков. ## Capabilities ### New Capabilities - `hook-guards`: блокирующие хуки обвязки — защита main/master/detached HEAD от записи (guard-main), требование плана для правок в коде (require-plan), их регрессионный корпус. ### Modified Capabilities Нет: `openspec/specs/` пуст, это первая capability обвязки. ## Impact - Код: `hooks/guard-main.sh`, `hooks/require-plan.sh` (становятся обёртками), новый `hooks/harness_target.py` (stdlib python3, новых зависимостей нет), `install.sh` (копирование и `--check`), `skills/harness-doctor/` (корпус, песочница, раннер, строка в отчёте), `docs/retro/scripts/hook_blocks_export.py`. - Тесты: `tests/test-hook-parse.sh`, `tests/test-hook-corpus.sh`, случаи require-plan. - Документация: `README.md`, `docs/HARNESS.md`, `CLAUDE.md` и `ARCHITECTURE.md` репозитория, `roles/dev.md` (уточнение про `cd`), `CHANGELOG.md` 0.4.0. - Установленные копии обновляются повторным `bash install.sh`; регистрация хуков в `settings.json` не меняется. - Вне задачи: B3 (allow-правило удаления веток), B4 кроме решения 1, B10 (workspace-хук awp-ca), запись в код через Bash для require-plan.