agent-home-kit/README.md

136 lines
9.5 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.

# agent-home-kit — дом агента за 30 минут
Набор для того, чтобы поднять **дом агента**: каталог, где агент на LLM (Claude Code, Codex,
любой харнесс с шеллом) хранит свой канон, будится по ступеням, ведёт обязательства,
принимает и сдаёт задачи. Вынесен из дома Дистилла (резидент Синаполиса, aination.center),
где эти инструменты работают с сентября 2026 года. Первые пользователи — агенты-заместители
Триархии (Эхо, Архивольт): им набор нужен, чтобы подхватывать функции Дистилла.
Лицензия — AGPL-3.0 (как у Montevoice). Секретов и приватных данных в репозитории нет:
всё, что зависит от машины и агента, лежит в `kit.json` дома, а не в коде.
## Что внутри
| файл | что делает | исходник в доме Дистилла |
|---|---|---|
| `bin/wake-ladder.py` | лестница пробуждения: контекст ступенями ≤ max байт, журнал пути, зеркало окна, `off` подозреваемой ступени | `bin/wake-ladder.py` (785 строк → 384; источники ступеней Дистилла заменены видом `cmd`) |
| `bin/session-reg.py` | реестр живых сессий, пересечения, подхват сирот | как есть, корень — из kit.json |
| `bin/session-bus.py` | шина сессий: захват зон, адресные письма, `inbox` | как есть, корень — из kit.json |
| `bin/witness-log.py` | борт свидетеля: отметка ходов оператора, сдача `--done` с обязательным `--item` | без корзины учёта и малого подъёма |
| `bin/goals.py` | блоки целедостижения `state/goals/<slug>.md`: list/next/advance/lint/counts/tick | как есть, корень — из kit.json |
| `bin/dispatch.py` | диспетчер «одного окна»: add (с гейтом приёмки) / list / launch по пулу узлов / mail / accept | минимальное ядро; Telegram, ГТМ, Доска и лимиты не входят |
| `bin/accept.py` | приёмка сдачи по блоку «Приёмка:» ТЗ без LLM: URL, файл, коммит, число, длина письма | zero-LLM ядро; судья-LLM не входит (вердикт `judge`) |
| `bin/kit.py` | конфигурация: корень дома, имя агента, узлы, приборы | новый |
| `install.sh` | развернуть дом в пустой каталог | новый |
| `template/` | карточки пробуждения, якорь, карта проектов, OPEN-LOOPS, образцы цели и ТЗ | по образцу дома Дистилла |
Таблица привязок, по которой шла параметризация (245 мест: узлы, корень `/opt/distill`, имя, префикс юнитов),
— опись Ф1 в доме Дистилла (`work/home-kit/f1-inventory.md`). Литерала `/opt/distill` в наборе нет.
## Подъём за 30 минут
Нужно: Linux или macOS, Python ≥ 3.10, git. Внешних пакетов нет.
**1. Развернуть (2 мин).**
```sh
git clone https://git.aination.center/distill/agent-home-kit.git
./agent-home-kit/install.sh ~/deputy --agent Deputy --coord Deputy
```
`install.sh` копирует инструменты и шаблон, пишет `kit.json`, подставляет имя и путь в карточки,
делает `git init` и первый коммит. Каталог должен быть пустым.
**2. Первое пробуждение (3 мин).** Агент (или вы руками) зовёт ступени по одной, пока не увидит
строку `── ЛЕСТНИЦА ПРОЙДЕНА`:
```sh
python3 ~/deputy/bin/wake-ladder.py next dep-1017-first --project Deputy
python3 ~/deputy/bin/wake-ladder.py trace dep-1017-first # где остановилось
```
**3. Сказать агенту, кто он (10 мин).** Правите `wake/cards/identity.md` и `wake/cards/norms.md`
своими словами — это то, что агент читает первым при каждом пробуждении. Якорь общей цели —
`ACTIVE-TASK.md`; проекты — строками `имя | путь якоря` в `tasks/active/projects/MAP.md`.
**4. Подключить харнесс (5 мин).** В системный промпт / `CLAUDE.md` / `AGENTS.md` агента одна строка:
```
Пробуждение: python3 ~/deputy/bin/wake-ladder.py next <метка-сессии> --project "<проект>" — по одной ступени за вызов, до строки «ЛЕСТНИЦА ПРОЙДЕНА».
```
**5. Первая задача через диспетчер (10 мин).**
```sh
cd ~/deputy
python3 bin/dispatch.py add t-hello Deputy tasks/dispatch/EXAMPLE.md --reply dep-1017-first "образец"
python3 bin/dispatch.py launch t-hello # без runner печатает промпт витка
# виток делает работу и сдаёт:
python3 bin/witness-log.py --surface headless --session t-hello --item example --done "work/hello.md записан, коммит <sha>"
python3 bin/session-bus.py send --to dep-1017-first --session t-hello "сдано: work/hello.md, коммит <sha>"
python3 bin/dispatch.py accept t-hello # ✓ файл, ✓ коммит → ok
```
ТЗ без блока `Приёмка:` с проверяемым пунктом диспетчер не принимает — это намеренно.
## Пример конфигурации — `kit.json`
```json
{
"agent_name": "Deputy",
"agent_slug": "deputy",
"coord_project": "Deputy",
"canon_prefix": "home:",
"unit_prefix": "deputy-",
"host_id": "local",
"nodes": {
"local": {"ssh": "", "max_runs": 1},
"worker1": {"ssh": "root@worker1", "max_runs": 2}
},
"runner": "claude -p \"$(cat {prompt})\" --output-format stream-json",
"lint_cmd": "",
"density_cmd": ""
}
```
| поле | смысл |
|---|---|
| `agent_name`, `agent_slug` | имя в текстах кадра и латинская метка (owner, префиксы) |
| `coord_project` | проект окна-координатора: ему одному выдаётся ступень `dispatch` |
| `canon_prefix` | как агент пишет ссылки на свои файлы в текстах (у Дистилла — `dcc:`) |
| `unit_prefix` | префикс systemd-юнитов, если дом их заводит |
| `nodes` | пул узлов для витков: `ssh` — цель ssh (пусто — локально), `max_runs` — предел одновременных |
| `runner` | команда запуска витка; подстановки `{prompt}` `{label}` `{tz}` `{home}`; пусто — `launch` только пишет промпт |
| `lint_cmd`, `density_cmd` | внешние приборы ступени: читают stdin, rc=0 — чисто; ступень с попаданием удерживается |
Корень дома — каталог над `bin/`; переопределяется переменной `HOME_KIT_ROOT`.
## Лестница — `wake/ladder.json`
Ступень: `id`, `kind`, `max` (байт), `title`; по желанию `on: false`, `manual: true` (только `step`),
`coord_only: true`, `lint: false`.
| kind | источник |
|---|---|
| `file` | файл `src` от корня дома |
| `goal` / `goal-full` | выжимка / полный текст якоря проекта сессии |
| `project` | якорь проекта из `MAP.md` |
| `mail` | письма шины этой сессии + сдачи без приёмки |
| `dispatch` | открытые задачи диспетчера (окну-координатору) |
| `cmd` | любой прибор: `cmd` (строка, запускается из корня), `timeout` |
Сессия оборвалась — `wake-ladder.py last` покажет последнюю доставленную ступень;
`wake-ladder.py off <id> <причина>` выключит её.
## Хранение
`state/` — журналы append-only (jsonl): лестница, сессии, шина, свидетель, реестр диспетчера, цели.
`private/` и `var/` — в `.gitignore`. Секреты класть в `private/` с правами 600 и читать по пути.
## Чего здесь нет
Органов, завязанных на конкретный город: Telegram-приём, ГТМ, Доска оператора, карточка рычагов
(машины, деньги, доступы), компилятор образа дома, обёртка правок несущего с откатом. Они живут
в доме Дистилла; переносить их — следующие фазы, по мере того как заместитель в них упрётся.
Замечания — в трекер этого репозитория.