Когда проект один, Claude Code хватает файла CLAUDE.md в корне репозитория. Когда проектов десять и к ним прилагаются серверы, инструкции расползаются: в одном репозитории записано, как оформлять коммиты, в другом нет; для одного сервера сказано спрашивать перед перезапуском сервиса, для другого не сказано. Правила копируются из файла в файл и перестают совпадать.
Я собрал общее в один каталог и назвал его harness. 10 октября 2026 года вышла версия 1.0.0 — первая с открытым кодом, под лицензией MIT. В статье — из чего он состоит, какие запреты в нём держит скрипт, а какие текст, и как открытая версия проверяется на личные данные перед публикацией. Все числа ниже пересчитаны по репозиторию версии 1.0.0.
Что это и из чего состоит
harness — каталог, из которого запускается claude. Проекты лежат внутри обычными клонами в repos/. В любой задаче агент получает одни и те же правила, реестр репозиториев и серверов и запись о том, какой репозиторий настраивает какой сервер. Собственный CLAUDE.md проекта остаётся и уточняет общие правила.
Установка — одна команда. Скрипт скачивает harness в ~/harness, проверяет зависимости и спрашивает имя, почту и язык.
curl -fsSL https://raw.githubusercontent.com/bukatchuk/harness/main/install.sh | bash
Нужен сам Claude Code. Остальные обязательные зависимости — git, jq, curl и bash версии 3.2 или новее, то есть штатный bash из macOS подходит. Для PR и релизов нужен gh, для локальных тестов — docker, для серверов — ssh с ключом.
В открытой версии 72 файла:
| Часть | Где лежит | Что это |
|---|---|---|
| CLI и хуки | bin/harness |
один bash-скрипт, 1493 строки |
| Правила | i18n/ru/rules, i18n/en/rules |
7 файлов: git, секреты, серверы, Docker, задачи, контекст, изменение самого harness |
| Skills | i18n/ru/skills, i18n/en/skills |
14 процедур: от коммита до публичного релиза |
| Шпаргалки | i18n/ru/integrations, i18n/en/integrations |
4 внешних сервиса: Plane, n8n, GitGuardian, Yandex Cloud |
| Реестр | registry/*.json |
проекты, серверы и связи между ними |
| Настройки | harness.json |
владелец, язык, подключённые интеграции |
Реестр и настройки — данные пользователя. В репозиторий harness они не входят, и обновление их не трогает.
Skill — это процедура по шагам, которую Claude Code выполняет по команде /имя или по обычной просьбе. Их четыре группы:
| Группа | Skills |
|---|---|
| Git | commit, push, pr-create |
| Проекты | repo-add, repo-remove, repo-sync |
| Серверы и связи | server-add, server-remove, service-add, service-remove |
| Сам harness | harness-doctor, harness-update, harness-reset, release-public |
Что проверяет скрипт, а что — правило
Правило — это текст, который агент читает в начале сессии. Он занимает место в контексте, и его исполнение ничем не гарантировано. Хук — команда, которая запускается перед каждой командой агента в терминале и может её отклонить. В правилах самого harness записано: прежде чем добавить правило, проверить, нельзя ли решить это скриптом или хуком.
Вот что в версии 1.0.0 держит скрипт:
| Что запрещено | Чем держится |
|---|---|
| Подменить автора коммита | хук отклоняет --author, -c user.*, git config user.*, GIT_AUTHOR_* |
| Добавить в коммит упоминание AI | хук читает текст коммита, тега, PR и релиза — и в команде, и в файле с сообщением |
| Закоммитить в harness без версии | git-хук требует поднять VERSION и дописать оба журнала изменений |
| Потерять несохранённую работу при удалении клона | команда отказывается без --force и называет числа |
| Удалить сервер, на который ссылаются связи | команда отказывается без --unlink |
| Сбросить реестр одной командой | без --yes команда печатает план и ничего не меняет |
Автор коммитов закрепляется при установке: имя и почта из harness.json записываются в окружение сессии. Команда с другим автором или со строкой Co-Authored-By не выполняется — хук возвращает ошибку раньше, чем git её увидит.
Правилами осталось то, что скриптом не проверить: когда спрашивать подтверждение, что считать секретом, что можно делать на сервере. Формулировка там такая: читать можно свободно, а всё, что меняет сервер или внешний сервис, — только после подтверждения с перечнем конкретных действий. Для серверов с пометкой prod агент дополнительно называет, что затронет действие и как его откатить.
Реестр проектов, серверов и связей
В реестре три файла. repos.json описывает проекты: адрес, ветка, стек, способ внесения изменений. servers.json — серверы: адрес, пользователь, окружение, назначение. services.json — связи: какой репозиторий отвечает за конфигурацию какого сервера и сервиса и как изменения туда доставляются.
Третий файл нужен, чтобы на вопрос «откуда это настраивается» отвечала команда, а не память:
bin/harness map <сервер | репозиторий | сервис>
Правило о серверах требует смотреть эту таблицу перед любой работой с сервером. Источник правды для конфигурации — репозиторий из связи; на самом сервере её не правят.
Удаление из реестра появилось в версии 1.0.0: repo-remove, server-remove, service-remove и reset. Перед каждым изменением реестр копируется в .harness-backup/ с меткой времени. Вернуть его можно, скопировав файлы обратно в registry/.
Два языка
Правила, skills и шпаргалки существуют в двух комплектах, русском и английском, по 26 файлов в каждом. Исходники лежат в i18n/, а Claude Code читает их копию на выбранном языке из каталога .claude/. Переключение — одна команда:
bin/harness lang en
Сообщения CLI тоже написаны парами. Чтобы комплекты не разошлись, их состав сверяют команда selfcheck и git-хук: коммит, в котором файл есть только на одном языке, не пройдёт. Собственные правила и skills пользователя лежат там же, в .claude/rules/ и .claude/skills/, и переключение языка и обновление их не трогают: скрипт ведёт список файлов, которые развернул сам, и меняет только их.
Сборка открытой версии и проверка на утечки
До версии 1.0.0 в правилах и шпаргалках стояли мои адреса, идентификаторы проектов и имя. В 1.0.0 я разделил репозиторий на ядро и данные: личное переехало в harness.json и registry/, а в правилах вместо имени написано «владелец».
Открытую версию собирает команда release-build. Она берёт файлы тега, убирает настройки, реестр и записи журнала, помеченные как закрытые, а потом ищет в результате:
- адреса почты, IP-адреса и идентификаторы UUID;
- пути домашних каталогов;
- ключи и токены;
- слова из настроек и реестра владельца — имена серверов и проектов, домены;
- секреты по базе GitGuardian, если установлен
ggshield.
Любая находка останавливает сборку. На пробной сборке перед релизом проверка остановилась на старом README, в котором был мой логин.
Публикация — отдельная команда. release-publish без ключа --push только показывает, что уйдёт. С ключом она добавляет в публичный репозиторий один коммит на релиз, ставит тег и прикладывает архив с контрольной суммой. История приватного репозитория в публичный не переносится: в нём сейчас один коммит.
Ограничения
- harness действует только на сессии, запущенные из его корня. Сессия Claude Code из другого каталога не получит ни правил, ни skills, ни хуков.
- Это bash-скрипт, и CI проверяет его на Ubuntu и macOS. На Windows он не проверялся.
- Реестр и настройки между устройствами не переносятся: их нужно хранить в своём приватном репозитории или в менеджере dotfiles.
- Интеграций четыре, и набор задан моими сервисами. Интеграция выключена, пока её ключа нет в
harness.json. - Хуки закрывают авторство, версии и удаление. Подтверждения перед действиями на серверах и во внешних сервисах — это правила; их исполнение хуками не проверяется.
- Проект новый: первый коммит сделан 9 октября 2026 года, в приватной истории 12 коммитов. На чужих установках он не проверялся.
Кому подойдёт
harness рассчитан на случай, когда репозиториев несколько, есть серверы и нужно, чтобы агент вёл себя одинаково во всех проектах, а коммиты оставались от имени владельца. Отдельные части можно забрать без остального: хук авторства, реестр связей, проверку релиза на утечки — всё это лежит в одном файле bin/harness.
Если проект один и серверов нет, файла CLAUDE.md в корне репозитория достаточно, и harness будет лишним.
Код, инструкция на русском и английском и журнал изменений — в репозитории bukatchuk/harness.