Я работаю с Claude Code параллельно на трёх подписках Pro. Коллеги — на своих. Часто работаем в одних и тех же файлах, в один день. Чтобы избежать потерь контекста, конфликтов и дублирования работы, я построила систему координации, вдохновлённую распределёнными системами 1980-х. Три слоя: handoffs, locks и почта. Ниже — как это работает.
Слой 1: Handoffs — «я закончил, подхватывай»
Когда новые сессии Claude приходилось каждый раз заново вводить в курс дела, я внедрила handoffs — короткие сводки в конце сессии, которые читает следующая.
Сначала писала всё в один файл HANDOFF.md. Но при нескольких чатах он быстро сломался: последняя запись перезаписывала остальные. Перешла на append-only модель: каждая сессия создаёт свой файл с уникальным именем.
Имя включает дату, время, первые 8 символов session-id и slug задачи. Два чата не могут создать файл с одинаковым именем — даже в одну секунду, потому что session-id разные. Гонка состояний невозможна без блокировок и брокеров.
Файл INDEX.md тоже append-only: новые записи добавляются в конец, старые не редактируются. Это аналог write-ahead log в базах данных: если сессия умрёт посреди записи, состояние останется согласованным.
Handoff — не дневник, а контракт со следующей сессией. Состоит из пяти секций:
- Цель — зачем сессия проводилась.
- Сделано — конкретные артефакты с путями.
- НЕ сработало — проваленные подходы с причинами.
- Текущее состояние — что работает, что сломано, что заблокировано.
- Следующий шаг — одно конкретное действие.
Пример handoff’а по проекту color-checker:
- Цель: «Color checker: CNN sweep + diffusion, первые результаты»
- Сделано: «CNN baseline median 1.99 deg, 11M params, 21 MB»
- НЕ сработало: «lr=3e-4 — NaN после epoch 10–13, нет gradient clipping»
- Сломано: «Diffusion training OOM на bs=16»
- Следующий шаг: «Inference скрипт для diffusion + visual sheets»
Самая ценная часть — «НЕ сработало». Она экономит часы на повторении ошибок. За четыре дня накопилось 27 handoff’ов — и ни одна ошибка не повторилась.
Handoff укладывается в 1500 токенов. Исходный контекст — около 100K. Компрессия — ~67×, без потерь ключевой информации.
Хуки вместо напоминаний
Писать handoff вручную неудобно. Решение — Stop-hook в Claude Code. Перед закрытием сессии он спрашивает: «Хочешь сохранить handoff?» если работа была содержательной.
На старте новой сессии я пишу: «подхвати handoff по color-checker» — и Claude читает нужный файл.
Иногда модель сама предлагает записать handoff — особенно после завершения крупной задачи или при заполнении контекста на 70–80%. Это её инициатива, а не мой запрос.
Запись — автоматическая (хук или модель). Чтение — одна фраза в начале сессии.
Rollups — когда handoff’ов становится слишком много
На долгих проектах накапливается по 80 handoff’ов. Новая сессия читает последние, а старые — игнорирует. В итоге повторяются уже опровергнутые гипотезы.
Решение — rollup’ы: один файл сворачивает 20 предыдущих handoff’ов. В нём — итог и граница: «свёрнуто до этой даты». Каждому исходному handoff’у добавляется строка rolled_up_into с именем rollup-файла.
Новая сессия читает только rollup и handoff’ы после его границы. Остальное — в архиве.
Имя rollup’а начинается с rollup_ — чтобы было видно в INDEX.md. Frontmatter содержит:
type: rollupcovers— список подчинённых файловthrough— дата-граница
Текст rollup’а — обычный handoff, но за 20 сессий. Паттерн не мой: аналог есть у PavelMuntyan/MF0-1984 в SQLite-схеме. Я адаптировала его под markdown-frontmatter.
Слой 2: Locks — «этот ресурс сейчас мой»
Handoff’ы не решают конфликты за ресурсы: модули кода, GPU, деплой-слоты. Две сессии не могут одновременно рефакторить один модуль — будет конфликт слияния. Или тренировать модель на одной GPU — вторая получит OOM.
Нужны блокировки. Для каждого ресурса — отдельный файл: auth-middleware.lock, gpu-host-a_gpu2.lock. В нём — кто взял, когда, для чего.
Создание файла — атомарное: os.open(path, O_CREAT | O_EXCL). Если файл уже есть — вызов падает. Это гарантирует ядро ОС. Тот же механизм, что у /var/lock и .pid-файлов с 1980-х.
Но lock без heartbeat бесполезен: если сессия упадёт, файл останется. Поэтому активная сессия обновляет timestamp раз в 30–60 минут. Если lock старше четырёх часов — возможно, сессия мертва.
«Возможно» — не «точно». Перед перехватом проверяю ресурс: SSH, nvidia-smi, git-статус. Только если ресурс свободен — перехватываю. Это принцип «доверяй, но проверяй» из Chubby и ZooKeeper.
Рядом с lock-файлом — JSON с метаданными: slug задачи, session-id, время захвата, описание, список файлов. Новая сессия за секунду видит: «auth-middleware занят под рефакторинг», «GPU 2 занята под тренировку».
Я пробовала автоматизировать lock’и через хук PreToolUse, но отказалась: команды слишком разнообразны, парсер дал бы ложные срабатывания. Правильный порядок — сначала соглашение и файлы, автоматизация — только для устойчивых паттернов.
Слой 3: Почта — «Артём, посмотри мой код»
Handoffs — для передачи контекста во времени. Locks — для ресурсов. Но не хватало синхронизации между живыми сессиями.
Раньше я спрашивала у коллеги: «Ты ещё делаешь middleware?» — он смотрел в свой чат, копировал ответ. Три перекладки. Каждый день.
Нужна прямая коммуникация между сессиями. Чтобы я написала — он ответил, я получила. Без одновременности. С гарантиями доставки.
Я поняла: это email.
Структура:
- Папка на каждого пользователя:
inbox,sent,archive - Папка
all/— для рассылок - Каждое письмо — markdown-файл с YAML frontmatter:
from,to,type,subject,message_id,in_reply_to,status
Пример: сессия ani пишет Артёму:
Ты менял линковку libsodium в CMakeLists? У меня build падает на target_link_libraries.
Через час Артём открывает свой чат. Хук проверяет inbox, видит письмо, подсовывает в контекст. Он отвечает — и ответ попадает в мой inbox.
Цепочки — через in_reply_to, как в RFC 822. Подтверждения — отдельные файлы-квитанции. Рассылка: to: * → папка all/. Дедупликация — через .watcher_state.json. Никакого брокера: всё на хуках.
Каждая фича — копия классического email:
- Mailbox агентов — Inbox per user
- Адресация — From / Reply-To
- Цепочки — In-Reply-To
- Статус — Read/Unread
- Аудит — Sent folder
- Подтверждение — Delivery receipt
Email решает ту же задачу: асинхронная доставка между процессами. Claude Code — новая упаковка старой проблемы.
mclaude: всё вместе
Я собрала три слоя в open-source инструмент — mclaude. Python, без зависимостей в ядре, 193 теста, v0.6.0.
Шесть слоёв:
- Locks — атомарный захват ресурсов + heartbeat
- Handoffs — per-session сводки, append-only INDEX
- Memory Graph — иерархическое хранилище решений и gotchas
- Identity Registry — имена сессий (ani, artem, nastya)
- Messages + Active Mail — межсессионная коммуникация с threading
- Code Indexer — AST-сканер →
code-map.md+llms.txt
Code Indexer — новинка v0.6.0. Сканирует проект, создаёт:
code-map.md— карта модулей, классов, функцийllms.txt— компактный индекс для быстрой загрузки
code-map.md читаем и человеком — формат взят из нашей базы знаний. Новая сессия не тратит время на перечитывание кода.
Ещё 5 хуков: на события Claude Code (SessionStart, PreToolUse, UserPromptSubmit, Stop) и git pre-commit guard, который блокирует коммит в заблокированный файл. MCP-сервер с 20+ инструментами отдаёт структурированный JSON — без парсинга CLI-вывода.
Принцип: hub — ускоритель, не зависимость. Всё работает на файлах. Hub поднят — сообщения через WebSocket. Упал — bridge пишет в .claude/messages/inbox/. Удалил mclaude — файлы остаются читаемыми. Markdown для нарратива, JSON для метаданных.
Чтобы увидеть паттерн за 30 секунд: pip install mclaude && mclaude demo --no-pause. Скрипт запускает две симулированные сессии (ani и vasya), проходит все слои и выводит Mermaid-диаграмму — её можно вставить в PR.
Дыра в экосистеме
Изоляция — решений много: Git worktrees, песочницы, отдельные порты, Anthropic Agent Teams. Всё это избегает общего состояния.
Координация общего состояния — почти пусто. Только claude_code_agent_farm от Dicklesworthstone делает file-based locks. Но это оркестрация 20+ агентов в tmux, а не сценарий многих чатов над одним проектом.
GitHub issue #19364 — запрос на «session lock file». Не реализован. Issue #29217 — .claude.json повреждается при параллельных записях. У одного пользователя — 315 битых бэкапов за 7 дней.
Экосистема зрелая в избегании общего состояния. Пустая в его координации.
Распределённые системы, вид сбоку
Всё это — паттерны из 1980-х:
- Heartbeat-таймауты для обнаружения мёртвых процессов
- Lock-файлы с именами по ресурсу
- Append-only журналы
- Внешняя проверка перед перехватом устаревшего замка
- Отдельный файл на ресурс — маленькое окно конфликта
Chubby, ZooKeeper, любая координационная система — всё это использует. AI-агенты — просто новый вид процессов в старой распределённой системе.
Email (RFC 822, 1982) оказался готовым решением для межагентной коммуникации. Не потому что «мы знаем email», а потому что он решает ту же абстрактную задачу: асинхронная доставка между процессами с цепочками и подтверждением.
Каждое поколение переоткрывает: email был прав. В 2010-х — это были очереди (RabbitMQ, Kafka). В 2026-м — AI-агенты.
Реальное использование
Три человека, один C++ проект, 6 параллельных сессий. Каждый работает над своей частью: архитектура, inference, UI.
Один агент решил изменить key derivation в scramble-модуле. Отправил рассылку через mailbox/all/. Другой увидел сообщение — и учёл изменение до начала кода. Без почты — был бы конфликт слияния или повреждение данных.
27 handoffs за 4 дня. 0 повторённых тупиков. Handoff между подписками сэкономил ~4 часа восстановления контекста.
Где сломается и чего не знаю
Масштаб. Тестировалось на 3–6 сессий, 2–3 человека, 1 C++ проект. Что будет при 20+ сессий от 10 агентов — неизвестно. Подозреваю, что .claude/messages/inbox/{user}/ станет узким местом: дедупликация через .watcher_state.json линейна, на сотнях писем будет медленно.
Между машинами без hub. Файловое ядро работает через общий репозиторий: закоммитил — другой увидел при git pull. Задержка — минуты, а не секунды. Hub даёт WebSocket, но требует отдельного процесса. В продакшне не испытан.
Race при взятии lock. O_CREAT | O_EXCL атомарен на локальной ФС. На сетевой (NFS, SMB) — зависит от реализации. При использовании .claude/locks/ на NFS возможна гонка.
Проверка устаревшего lock — полуавтоматическая. Перед перехватом я вручную проверяю nvidia-smi, ps, git-статус. Для полной автоматизации нужен обработчик, знающий типы ресурсов. Пока — человек решает.
Почта без push-доставки. Сейчас письма показываются на UserPromptSubmit — только когда сессия что-то пишет. Настоящая push-доставка (сессия просыпается при письме) — в планах.
Human-in-the-loop нужен. Система не заменяет координатора. Если 6 агентов решат переделать auth-middleware — они договорятся, но кто именно возьмёт задачу, решает человек. Mclaude даёт инструменты, не автономность.
Что дальше
mclaude — open source, MIT. 193 теста, Python 3.9+.
Репозиторий: github.com/AnastasiyaW/mclaude. Принципы: claude-code-config/principles/18.
Что доделываю:
- Автопробуждение сессии при новом письме. Сейчас хук срабатывает на
UserPromptSubmit. Правильно — будить сессию при приходе письма. Будет в ближайшем обновлении. - Наблюдение за перепиской команды. Дашборд, который читает
.claude/messages/и показывает ленту: кто кого спрашивает, где затыки. Мониторинг без открытия чатов. - Трекер задач для агентской команды. Хаб, где задача ставится конкретному Claude’у коллеги. Видно состояние, можно переключить исполнителя. Почему это не Jira — отдельный разговор.