Pular para o conteúdo principal

Documentação oficial desta página · v0.20.6

Faixas de Trabalho do Kanban

Uma faixa de trabalho (worker lane) é uma classe de processo para a qual o despachante do kanban consegue rotear tarefas. Cada faixa tem uma identidade (a string de responsável), um mecanismo de criação de processo e um contrato do que ela precisa fazer com a tarefa depois de iniciada.

Esta página é o contrato. Ela existe para dois públicos:

  • Operadores escolhendo quais faixas ligar a um quadro (quais perfis criar, quais responsáveis usar).
  • Autores de plugin ou integração querendo acrescentar um novo formato de faixa (um worker de linha de comando que embrulha Codex / Claude Code / OpenCode, um worker de revisão em contêiner, um serviço fora do Hermes que puxa tarefas pela API).

Se você está escrevendo o código do worker em si — o agente que roda dentro de uma faixa —, o ciclo de vida do kanban e os detalhes de referência já são injetados no prompt de sistema do worker automaticamente (o bloco KANBAN_GUIDANCE em agent/prompt_builder.py).

A hierarquia​

Kanban do Hermes = ciclo de vida canônico da tarefa + trilha de auditoria
Faixa de trabalho = executor da implementação de um cartão atribuído
Revisor = humano ou procurador de humano que libera o "pronto"
PR no GitHub = artefato que dá para subir (opcional, para faixas de código)

O Kanban do Hermes é dono da verdade do ciclo de vida — ready → running → review / blocked / done / archived. As faixas de trabalho executam o trabalho, mas nunca são donas dessa verdade; tudo o que elas fazem volta ao núcleo do kanban pelas ferramentas kanban_* (ou, para workers externos fora do Hermes, pela API). Os revisores liberam a transição de "mudança de código escrita" para "tarefa pronta".

O que uma faixa fornece​

Para ser uma faixa de trabalho do kanban, uma integração precisa fornecer três coisas:

1. Uma string de responsável​

O despachante casa task.assignee ou com o nome de um perfil do Hermes (o formato de faixa padrão) ou com um identificador não iniciável registrado (o formato de faixa por plugin — veja Acrescentar uma faixa de worker de CLI externa abaixo). Tarefas cujo responsável não resolve ficam em ready com um evento skipped_nonspawnable para que o operador do quadro possa corrigi-las; elas não são descartadas em silêncio nem executadas por um plano B qualquer.

2. Um mecanismo de criação de processo​

Para faixas de perfil do Hermes, o _default_spawn do despachante roda hermes -p <responsável> chat -q <prompt> (ou a forma equivalente por módulo, quando o atalho hermes não está no $PATH) dentro do espaço de trabalho fixado da tarefa, com estas variáveis de ambiente definidas:

VariávelCarrega
HERMES_KANBAN_TASKo id da tarefa em que o worker está trabalhando
HERMES_KANBAN_DBcaminho absoluto do arquivo SQLite daquele quadro
HERMES_KANBAN_BOARDo slug do quadro
HERMES_KANBAN_WORKSPACES_ROOTraiz da árvore de espaços de trabalho do quadro
HERMES_KANBAN_WORKSPACEcaminho absoluto do espaço de trabalho desta tarefa
HERMES_KANBAN_RUN_IDo id da execução atual (para a trava de ciclo de vida)
HERMES_KANBAN_CLAIM_LOCKa string da trava de reivindicação (<host>:<pid>:<uuid>)
HERMES_PROFILEo nome do próprio perfil do worker (para a autoria em kanban_comment)
HERMES_TENANTespaço de nomes do inquilino, se a tarefa tiver um

Para faixas fora do Hermes (registradas por um plugin), o plugin fornece o próprio spawn_fn, um chamável que recebe task, workspace e board e devolve um pid opcional para detecção de queda.

3. Um encerrador de ciclo de vida​

Toda reivindicação precisa terminar em exatamente uma destas opções:

  • kanban_complete(summary=..., metadata=...) — a tarefa deu certo, o status vira done.
  • kanban_request_review(summary=..., metadata=..., reviewer=...) — a implementação no mesmo cartão está completa e entra em revisão de primeira classe; o status vira review. O despachante carrega a skill embutida sdlc-review, a menos que kanban.review_dispatch esteja desligado. Um revisor aprova com kanban_complete, devolve retrabalho acionável com kanban_request_changes ou escala um impedimento externo de verdade com kanban_block.
  • kanban_block(reason=...) — a tarefa espera por uma pessoa, o status vira blocked. O despachante cria o processo de novo quando o kanban_unblock roda.
  • O processo do worker sai sem chamar ferramenta nenhuma. O núcleo o recolhe e emite crashed (o PID morreu), gave_up (o disjuntor de falhas consecutivas abriu) ou timed_out (o max_runtime estourou). Este é o caminho de falha; workers saudáveis não terminam assim.

O núcleo do kanban garante que exatamente uma dessas opções encerra cada execução. Um worker que não chama nenhuma delas e sai normalmente é tratado como queda.

Saídas e a passagem para a revisão​

Para tarefas que mudam código, escolha o modelo de revisão codificado no grafo de tarefas:

  • Revisão no mesmo cartão: chame kanban_request_review(summary=..., metadata=..., reviewer=...). A tarefa entra em review sem mexer na contabilidade de recorrência de bloqueio. O despachante a reivindica com a skill embutida sdlc-review por padrão. O revisor aprova com kanban_complete, chama kanban_request_changes(reason=...) para fechar a execução de revisão e devolver a tarefa a quem a implementou, ou bloqueia apenas diante de uma escalada externa de verdade.
  • Cartão de revisão/QA/release já criado a jusante: o kanban_show lista os IDs filhos; inspecione esses cartões com kanban_show(task_id=...) antes de escolher a ação terminal. Quando um filho é a fase de revisão/QA/release a jusante, chame kanban_complete na fase de implementação. Ele não consegue avançar enquanto este pai não estiver done/archived. Não peça também revisão no mesmo cartão e nunca deixe o pai bloqueado de forma fixa com review-required: — qualquer uma das duas escolhas abandona ou duplica a faixa a jusante.
  • Quadros só de humanos: defina kanban.review_dispatch: false. Aí a tarefa pode ficar em review até uma pessoa aprová-la ou usar o reopen-review/o painel para devolvê-la a ready/todo.

Os dois modelos de revisão carregam a passagem estruturada na própria transição de ciclo de vida. Não coloque segredos, tokens ou dados pessoais crus em summary nem em metadata; as linhas de execução são duráveis.

O KANBAN_GUIDANCE injetado cobre os dois formatos de grafo, o kanban_complete, o laço de revisão no mesmo cartão e o kanban_block para impedimentos de verdade.

Logs e trilha de auditoria​

O despachante grava a saída padrão e a de erro de cada worker em <raiz-do-quadro>/logs/<task_id>.log. Os logs são auditáveis a partir dos metadados do kanban:

  • As linhas de task_runs carregam o log_path, o código de saída (quando disponível), o resumo e os metadados.
  • As linhas de task_events carregam toda transição de estado (promoted, claimed, heartbeat, completed, blocked, review_requested, changes_requested, review_reopened, gave_up, crashed, timed_out, reclaimed, claim_extended).
  • O kanban_show devolve as duas coisas, então um revisor (ou um worker seguinte) que leia a tarefa recebe o histórico inteiro sem precisar de acesso ao painel.

O painel desenha o histórico de execuções com resumos, blocos de metadados e selos de status de saída. Quem usa a CLI pode rodar hermes kanban tail <task_id> para acompanhar ao vivo, ou hermes kanban runs <task_id> para a lista histórica de tentativas.

Formatos de faixa existentes​

Faixa de perfil do Hermes (padrão)​

O formato que toda faixa de trabalho do kanban tem hoje: o responsável é um nome de perfil, o despachante inicia hermes -p <perfil>, o worker recebe o bloco de prompt de sistema KANBAN_GUIDANCE automaticamente e usa as ferramentas kanban_* para encerrar a execução. Sem nenhuma configuração além de definir o perfil.

Quando você criar perfis para a sua frota, escolha nomes que combinem com o papel para o qual você quer que o orquestrador roteie. O orquestrador (quando existe um) descobre os seus nomes de perfil por hermes profile list — não há um elenco fixo que o sistema pressupõe (o lado do orquestrador no contrato faz parte do KANBAN_GUIDANCE injetado).

Faixa de perfil orquestrador​

Uma especialização da faixa de perfil: um orquestrador é um perfil do Hermes cujo conjunto de ferramentas inclui kanban mas exclui terminal / file / code / web para implementação. A função dele é decompor uma meta de alto nível em tarefas filhas com kanban_create + kanban_link e sair de cena. A skill de orquestrador codifica as regras contra a tentação.

Acrescentar uma faixa de worker de CLI externa​

Ligar uma ferramenta de linha de comando fora do Hermes (Codex CLI, Claude Code CLI, OpenCode CLI, um executor local de modelo de código etc.) como faixa de trabalho do kanban ainda não é um caminho pavimentado. A função de criação de processo do despachante é plugável (spawn_fn é um parâmetro de dispatch_once), e um plugin poderia registrar o próprio spawn_fn para um responsável fora do Hermes, mas o trabalho de integração ao redor — embrulhar o código de saída da CLI em chamadas de kanban_complete / kanban_block, mapear as convenções de espaço de trabalho e sandbox da CLI sobre a variável HERMES_KANBAN_WORKSPACE do despachante, cuidar de autenticação e da política de cada CLI — ainda é projeto sob medida por integração.

Se você está pensando em acrescentar uma faixa de CLI, abra uma issue descrevendo a CLI específica e o fluxo que quer viabilizar. O contrato acima traz as restrições que qualquer faixa dessas precisa satisfazer; o formato da implementação (um plugin por CLI ou um plugin genérico de executor de CLI parametrizado por configuração) está em aberto.

A issue histórica disso é a #19931, e o PR específico do Codex fechado sem merge é o #19924 — eles descrevem a proposta original de arquitetura, mas não entregaram um executor.

Modos de falha que o despachante já trata​

Para que os autores de faixa não precisem reimplementar isto:

  • TTL de reivindicação parada — um worker que reivindica e depois nunca manda batimento, nem completa, nem bloqueia é reivindicado de novo depois de DEFAULT_CLAIM_TTL_SECONDS (15 min por padrão) — mas só se o processo do worker realmente morreu. Um worker vivo (modelo lento passando 20 minutos ou mais numa única chamada de LLM sem ferramenta) tem a reivindicação estendida em vez de morta; só um PID morto é reivindicado de novo.
  • Worker caído — um worker cujo PID local no host sumiu é detectado por detect_crashed_workers e recolhido; a tarefa incrementa consecutive_failures e pode se autobloquear quando o disjuntor abre.
  • Nova tentativa no nível da execução — quando uma tarefa é repetida (depois de bloqueio, de queda ou de nova reivindicação), o worker pode usar o parâmetro expected_run_id nas ferramentas de encerramento para falhar rápido se a própria execução dele já foi superada.
  • Tempo máximo de execução por tarefa — task.max_runtime_seconds limita o tempo de relógio por execução, independentemente de o PID estar vivo. Pega workers de fato travados que a extensão por PID vivo manteria rodando.
  • Detecção de tarefa abandonada — uma tarefa em ready cujo responsável nunca produz uma reivindicação dentro de kanban.stranded_threshold_seconds (padrão 30 min) aparece em hermes kanban diagnostics como um aviso stranded_in_ready. A severidade sobe para erro no dobro do limite e para crítico em 6 vezes. Pega responsáveis com erro de digitação, perfis apagados e pools de workers externos fora do ar num sinal só — sem depender de identidade, sem lista de permissão por quadro para manter.
  • Impasse de dependência na revisão antiga — um pai bloqueado de forma fixa com review-required: enquanto um ou mais filhos diretos continuam presos por dependência em todo produz um erro imediato de review_dependency_deadlock. O diagnóstico é somente leitura: ele sugere concluir a fase terminada ou desfazer a aresta errada, mas nunca remove um bloqueio criado por você.