Полосы канбан-воркеров
Полоса воркера — это классный процесс, к которому диспетчер канбаны может направить задачу. Каждая полоса имеет идентификатор (строка назначения), механизм порождения и контракт на то, что она должна сделать с устройством после порождения.
На этой странице и есть контракт. Она существует для двух аудиторий:
- Операторы, выбирающие, какие полосы подключаются к доске (какие профили создают, какие используются).
- Авторов плагинов/интеграций, желающие добавить новые формы полос (CLI-воркер, оборачивающий Codex/Claude Code/OpenCode, контейнерный воркер для ревью, негермесовый, сервисный получающий задачи через API).
Если вы пишете сам код воркера — агента, который работает внутри группы, — навыки kanban-worker содержит более глубокие процедурные детали.
Иерархия
Hermes Kanban = канонический жизненный цикл задачи + аудиторский след
Полоса воркера = исполнитель реализации для одной назначенной карточки
Ревьюер = человек или прокси-человек, который ставит шлюз "готово"
GitHub PR = артефакт, готовый к отправке в вышестоящий репозиторий (опционально, для кодовых полос)
Hermes Kanban владеет истиной жизненного цикла — ready → running → blocked / done / archived. Полосы воркеров выполняют работу, но никогда не владеют этой истиной; всё, что они делают, возвращается обратно в ядро канбана через инструменты kanban_* (или, для внешних не-Hermes воркеров, через API). Ревьюеры ставят шлюз на переходе от "изменение кода написано" к "задача выполнена".
Что предоставляет полоса
Чтобы быть полосой канбан-воркера, интеграция должна предоставить три вещи:
1. Строка назначения
Диспетчер сопоставляет task.assignee либо с именем профиля Hermes (форма полосы по умолчанию), либо с зарегистрированным непорождаемым идентификатором (форма полосы плагина — см. Добавление внешней полосы CLI-воркера ниже). Задачи, чьё назначение не разрешается, остаются в статусе ready с событием skipped_nonspawnable, чтобы оператор доски мог их исправить; они не молча отбрасываются и не выполняются произвольным запасным вариантом.
2. Механизм порождения
Для полос профилей Hermes диспетчерский _default_spawn запускает hermes -p <assignee> chat -q <prompt> (или эквивалентную модульную форму, когда обёртка hermes отсутствует в $PATH) внутри закреплённого рабочего пространства задачи, с установленными переменными окружения:
| Переменная | Содержит |
|---|---|
HERMES_KANBAN_TASK |
идентификатор задачи, над которой работает воркер |
HERMES_KANBAN_DB |
абсолютный путь к SQLite-файлу доски |
HERMES_KANBAN_BOARD |
слаг доски |
HERMES_KANBAN_WORKSPACES_ROOT |
корень дерева рабочих пространств доски |
HERMES_KANBAN_WORKSPACE |
абсолютный путь к рабочему пространству этой задачи |
HERMES_KANBAN_RUN_ID |
идентификатор текущего запуска (для шлюза жизненного цикла) |
HERMES_KANBAN_CLAIM_LOCK |
строка блокировки захвата (<host>:<pid>:<uuid>) |
HERMES_PROFILE |
имя профиля самого воркера (для атрибуции автора комментария kanban_comment) |
HERMES_TENANT |
пространство имён арендатора, если у задачи оно есть |
Для не-Hermes полос (зарегистрированных через плагин) плагин предоставляет собственную вызываемую spawn_fn, которая получает task, workspace и board и возвращает опциональный PID для обнаружения сбоев.
3. Терминатор жизненного цикла
Каждый захват должен завершаться ровно одним из:
kanban_complete(summary=..., metadata=...)— задача успешно выполнена, статус переключается наdone.kanban_block(reason=...)— задача ожидает ввода от человека, статус переключается наblocked. Диспетчер перезапускает, когда выполняетсяkanban_unblock.- Процесс воркера завершается без вызова инструмента. Ядро обрабатывает его и выдаёт
crashed(PID умер) илиgave_up(сработал автоматический выключатель последовательных сбоев) илиtimed_out(превышено максимальное время выполнения). Это путь отказа; здоровые воркеры здесь не заканчиваются.
Ядро канбана гарантирует, что ровно один из этих вариантов завершает каждый запуск. Воркер, который не вызывает ни один из них и завершается нормально, считается упавшим.
Результаты и соглашение о необходимости ревью
Для большинства задач, изменяющих код, работа не является по-настоящему завершённой в момент окончания воркера — нужен человек-ревьюер. Ядро канбана не принуждает к этому различию ("задача, изменяющая код" — размытое понятие, и принудительная блокировка вместо завершения для каждого кодового воркера сломала бы потоки, где ревью не требуется). Это соглашение, надстроенное сверху:
- Блокировать вместо завершения, с префиксом
review-required:вreason, чтобы панель управления /hermes kanban showотображали строку как ожидающую ревью. - Сначала помещать структурированные метаданные в
kanban_comment, посколькуkanban_blockнесёт только человекочитаемыйreason. Комментарии — это долговечный канал аннотаций; все релевантные для аудита поля (изменённые файлы, запущенные тесты, путь к diff или URL PR, решения) должны быть там. - Ревьюер либо одобряет и разблокирует, что перезапускает воркера с цепочкой комментариев для последующих действий; либо запрашивает изменения через другой комментарий, который следующий запуск воркера увидит как часть контекста
kanban_show.
Навык kanban-worker содержит рабочие примеры как для kanban_complete (действительно терминальные задачи — исправление опечаток, изменения в документации, исследовательские записки), так и для шаблона блокировки review-required.
Логи и аудиторский след
Диспетчер записывает stdout/stderr воркера для каждой задачи в <board-root>/logs/<task_id>.log. Логи доступны для аудита из метаданных канбана:
- Строки
task_runsсодержатlog_path, код возврата (где доступен), сводку и метаданные. - Строки
task_eventsсодержат каждый переход состояния (promoted,claimed,heartbeat,completed,blocked,gave_up,crashed,timed_out,reclaimed,claim_extended). kanban_showвозвращает и то, и другое, так что ревьюер (или последующий воркер), читающий задачу, получает полную историю без необходимости доступа к панели управления.
Панель управления отображает историю запусков со сводками, блоками метаданных и значками статуса завершения. Пользователи CLI могут запустить hermes kanban tail <task_id> для наблюдения в реальном времени или hermes kanban runs <task_id> для исторического списка попыток.
Существующие формы полос
Полоса профиля Hermes (по умолчанию)
Форма, которую сегодня принимает каждый канбан-воркер: назначение — это имя профиля, диспетчер запускает hermes -p <profile>, воркер автоматически загружает навык kanban-worker плюс блок системного промпта KANBAN_GUIDANCE и использует инструменты kanban_* для завершения запуска. Никакой настройки, кроме определения профиля.
Когда вы создаёте профили для своего флота, выбирайте имена, соответствующие роли, на которую вы хотите, чтобы оркестратор направлял задачи. Оркестратор (когда он есть) обнаруживает имена ваших профилей через hermes profile list — нет фиксированного списка, который система предполагает (см. навык kanban-orchestrator для стороны контракта оркестратора).
Полоса профиля оркестратора
Специализация полосы профиля: оркестратор — это профиль Hermes, чей набор инструментов включает kanban, но исключает terminal / file / code / web для реализации. Его задача — декомпозировать высокоуровневую цель на дочерние задачи через kanban_create + kanban_link и отступить. Навык оркестратора кодирует правила против соблазна.
Добавление внешней полосы CLI-воркера
Подключение не-Hermes CLI-инструмента (Codex CLI, Claude Code CLI, OpenCode CLI, локальный запускатель кодовых моделей и т.д.) в качестве полосы канбан-воркера пока не является проторённым путём. Функция порождения диспетчера подключаема (spawn_fn — это параметр dispatch_once), и плагин может зарегистрировать свою собственную spawn_fn для не-Hermes назначения, но окружающая работа по интеграции — обёртывание кода возврата CLI в вызовы kanban_complete / kanban_block, сопоставление соглашений CLI о рабочем пространстве/песочнице с переменной окружения HERMES_KANBAN_WORKSPACE диспетчера, обработка аутентификации и политик для каждого CLI — всё ещё является проектной работой для каждой интеграции.
Если вы рассматриваете добавление CLI-полосы, откройте issue, описывающее конкретный CLI и рабочий процесс, который вы пытаетесь реализовать. Контракт выше — это ограничения, которым должна удовлетворять любая такая полоса; форма реализации (один плагин на CLI против универсального плагина-запускателя CLI, параметризованного конфигурацией) открыта.
Исторический issue для этого — #19931 и закрытый, но не слитый PR, специфичный для Codex, — #19924 — они описывают исходную архитектурную proposal, но не привели к появлению запускателя.
Режимы отказа, которые обрабатывает диспетчер
Чтобы авторам полос не пришлось реализовывать их заново:
- Истекший TTL захвата — воркер, который захватил задачу, а затем никогда не отправляет heartbeat / не завершает / не блокирует, будет отозван после
DEFAULT_CLAIM_TTL_SECONDS(по умолчанию 15 мин) — но только если процесс воркера действительно умер. Живой воркер (медленная модель, тратящая 20+ минут на один вызов LLM без инструментов) получает продление захвата вместо убийства; только мёртвый PID отзывается. - Упавший воркер — воркер, чей локальный PID исчез, обнаруживается
detect_crashed_workersи обрабатывается; задача увеличиваетconsecutive_failuresи может автоматически заблокироваться при срабатывании выключателя. - Повтор на уровне запуска — когда задача повторяется (после блокировки, сбоя, отзыва), воркер может использовать параметр
expected_run_idв завершающих инструментах, чтобы быстро завершиться ошибкой, если его собственный запуск уже был заменён. - Максимальное время выполнения задачи —
task.max_runtime_secondsжёстко ограничивает астрономическое время на запуск, независимо от живости PID. Ловит действительно заблокированные воркеры, которые продление живого PID иначе держало бы работающими. - Обнаружение зависших задач — задача в статусе
ready, чьё назначение никогда не приводит к захвату в течениеkanban.stranded_threshold_seconds(по умолчанию 30 мин), отображается вhermes kanban diagnosticsкак предупреждениеstranded_in_ready. Серьёзность повышается до ошибки при 2x порога и до критической при 6x. Ловит опечатки в назначениях, удалённые профили и неработающие внешние пулы воркеров одним сигналом — независимо от идентичности, без необходимости вести разрешённый список для каждой доски.
Связанное
- Обзор канбана — введение для пользователя.
- Учебник по канбану — пошаговое руководство с открытой панелью управления.
kanban-worker— навык, который загружает процесс воркера.kanban-orchestrator— сторона оркестратора.