O swarm L3 é como o Alembic roda muitas unidades de trabalho concorrentemente e sobrevive a crashes. Um orquestrador de 3 camadas com profundidade limitada sobre uma fila de tasks com portão de dependências, com estado filesystem-como-verdade, isolamento por git-worktree, um park T4 duro, e resume seguro a crash. É o pacote que a matriz de fusão diz ter tornado o delegate_tool.py do Hermes um IGNORE — o Alembic já delega, nativamente e melhor. Fonte: packages/swarm/.
A hierarquia de papéis é orchestrator → lead → worker, e é limitada: MAX_DEPTH = 2. Um nó na profundidade máxima é uma folha e não pode spawnar; subtasks são tasks-folha, então o aninhamento é estruturalmente de um nível. É uma guarda deliberada contra fan-out recursivo descontrolado:
Só tasks ready rodam. Uma task se torna ready quando todos os seus dependsOn alcançam sucesso-terminal (done). O orquestrador nunca roda uma task cujos pré-requisitos não tenham de fato tido sucesso — o grafo de dependências é honrado, não torcido. Tipos de worker:
| Tipo de worker | O que roda |
|---|---|
| model worker | uma chamada de adapter (o run() da lição 14) |
| command worker | taskSpec.command → um subprocesso real; saída 0 → done |
| background worker | taskSpec.background → um filho destacado que sobrevive à morte do pai e re-anexa ao seu report no resume (requer command, proíbe isolate) |
O estado é durável no disco: um journal events.jsonl append-only mais um checkpoint.json. O resume reproduz o último checkpoint e todo evento task-state (idempotente, o último-por-id vence). A parte engenhosa é como ele trata um worker que morreu no meio do voo:
// packages/swarm/src/orchestrator.ts:706-755 (condensado) — replayInto // reproduz checkpoint + todo evento task-state (último-por-id vence, idempotente) // uma task 'running' órfã (worker morreu) é rebaixada a 'ready' e re-tentada // ⇒ execução pelo-menos-uma-vez; enqueue é idempotente então o denominador do // monitor cobre toda task mesmo após um crash no meio da declaração
Todo valor que cruza uma fronteira de durabilidade é parseado por Zod na leitura, então uma linha de journal corrompida ou editada à mão é rejeitada na fronteira em vez de confiada em silêncio (filesystem-como-verdade, invariante ③ da lição 16). A unicidade global de id por toda a árvore é validada antes de qualquer coisa ser jornalada, então um id duplicado não pode envenenar um resume.
isolate: true sem config de worktree é um erro, nunca uma run sem-isolamento em silêncio. Se você pediu isolamento e o ambiente não pode prover, a run para — ela não executa sua task quietamente contra a working tree compartilhada. Um command worker que não pode tocar o checkout principal recebe um git worktree via withWorktree, ou não roda.
Tasks irreversíveis / legais / de segurança / T4 são roteadas para o ledger do park e nunca auto-executadas. O park é idempotente entre resumes e estruturalmente protegido — uma task estacionada é imóvel. As razões de park são um conjunto fechado: tier-t4 / irreversible / legal / security / manual. Esta é a expressão em nível de swarm do princípio do portão humano: o motor recusa dar o passo perigoso por conta própria, e você o reabre com alembic approve/reject/propose.
O sinal de reward (computeReward) é um escalar heurístico moldado — estilo PARL, não aprendizado por reforço — e tem portão HITL por requiresApproval. O nome evoca RL; a implementação é uma heurística determinística com um humano no loop.
replayInto reproduz o checkpoint mais os eventos task-state; uma task deixada running por um worker morto é rebaixada a ready e re-rodada. Combinado com enqueue idempotente, o resume cobre toda task mesmo após um crash no meio da declaração.isolate: true mas nenhuma config de worktree é fornecida. O que o orchestrator faz?computeReward é um escalar heurístico moldado, explicitamente não RL, e tem portão HITL por requiresApproval. O reward molda a priorização com um humano no loop; não há gradiente, não há treino.