Passo 4 · Módulo 2 · Orquestração · Swarm, harness & gates
Curso do Produto Alembic · Visual Course

Swarm, harness & gates: como um signal vira venture com prova

No fim desta lição você vai entender como o Alembic pega o signal "fábrica de petições personalizadas" e o forja em uma venture — orquestrando agentes (um lead que distribui trabalho a workers), provando cada passo na fronteira real, e deixando cada uma das cinco porteiras (Scope → Council → Proof → Validator → Publish) liberar — ou travar — o passo seguinte.

Leia primeiro (fonte primária)
packages/coda/src/proof.ts — o Proof Gate que falha fechado

Esta lição destila o coração da orquestração: packages/swarm/src (lead→workers), packages/harness/src (o core + HTTP/SSE/MCP), packages/mission/src/compiler.ts (units → tasks + proof) e packages/coda/src (os gates). Para um produto interno, a fonte da verdade é o código + a saída real do CLI — nada de memória.

Leia a versão simples, ou abra a camada técnica em qualquer seção.

Na lição 1 você viu o Alembic como duas metades: o motor de destilação (lê o corpus, produz LEARNINGS + SIGNALS) e o harness de agentes (pega um signal e o forja em produto). As lições 2 e 3 cobriram a primeira metade. Agora abrimos a segunda: como o harness orquestra agentes para construir, e como cada porteira garante que nada irreversível escape sem prova. O nosso signal — "fábrica de petições personalizadas" — vira aqui uma venture, passo a passo, com cada passo verificado na fronteira real.

Suposições tolas (o que assumo de você)

Assumo muito pouco: que você já viu um comando de terminal e sabe que um programa pode "dar certo" (sair com código 0) ou "dar errado" (sair com código diferente de 0). Não assumo que você sabe o que é orquestração de agentes, um gate, SSE ou MCP — tudo isso é definido no primeiro uso. O nome "tolas" é uma piada interna da série For Dummies: você é esperto, só é novo no assunto.

1

A grande ideia


Forjar um produto é trabalho demais para um agente só. O Alembic resolve isso como uma oficina com hierarquia: um orquestrador abre a obra, um lead (líder de equipe) quebra a obra em tarefas e as distribui para vários workers (operários) que trabalham em paralelo. Cada operário faz UMA peça e entrega um relatório.

Mas velocidade sem controle é perigoso. Então, entre o trabalho e o "pronto", existe uma esteira de cinco porteiras (gates). Cada porteira inspeciona a peça e só libera a próxima se a anterior passou. Se uma prova falha, a esteira para — em vez de empurrar trabalho quebrado adiante. É isso que significa falhar fechado.

Pense como… uma linha de montagem de carros com estações de inspeção. O gerente (orquestrador) abre o turno, o chefe de linha (lead) escala os montadores (workers), e cada carro passa por postos de qualidade. Se o teste de freio reprova, o carro não segue para a pintura — a linha trava ali. Onde a analogia quebra: aqui os "montadores" são chamadas a modelos de IA ou subprocessos, e o "carro" é um pedaço de software (ou uma campanha, ou uma venture).

Por baixo do capô

São três papéis, ordenados por profundidade: orchestrator (0) → lead (1) → worker (2). A profundidade é estruturalmente limitada: MAX_DEPTH = 2, e um worker é uma folha que não pode gerar mais ninguém — isso é garantido tanto no schema (subtasks não aninham) quanto em runtime (canSpawn). Todo valor que cruza uma fronteira de durabilidade (linha JSONL, checkpoint, arquivo de relatório) é um schema Zod validado na leitura — o filesystem é a fonte da verdade, então uma linha corrompida é rejeitada na borda, nunca confiada.

O harness em si é um core neutro de transporte: a classe HarnessCore tem quatro verbos (start / poll / fanout / report) e não sabe como foi invocada. CLI, HTTP+SSE e MCP são adaptadores finos sobre o mesmo objeto. As cinco porteiras vivem em packages/coda/src e cada etapa fail-closed devolve Result<T, Error> — a cintura estreita da lição 1.

Lembre 🧵 — Uma frase para levar: velocidade vem do lead→workers em paralelo; segurança vem dos gates que falham fechado. O Alembic insiste nos dois ao mesmo tempo.
2

Objetivos desta lição


Ao terminar, você vai conseguir:

  • Explicar os três papéis orchestrator → lead → worker e por que a profundidade é limitada a 2.
  • Descrever como um lead distribui subtarefas em rajada controlada (ramp) e coleta relatórios por arquivo.
  • Ler uma missão com units[] e proof[] e dizer o que vira tarefa e o que vira prova.
  • Percorrer a esteira de cinco gates e apontar qual delas trava em cada tipo de risco.
  • Reconhecer as três superfícies de operação — run, serve, cockpit — e o que cada uma expõe.
  • Provar o default de autonomia do Alembic com alembic status (tier T4, as 7 fases).
3

O harness em uma imagem


O harness tem um conductor único no meio (o HarnessCore) que não sabe como foi chamado. Você pode falar com ele de três jeitos — pela linha de comando, por HTTP, ou por MCP — e os três acionam o mesmo motor. Esse motor conduz duas coisas: o council (a deliberação) e o swarm (a execução).

TRANSPORTES (adaptadores finos) CLI alembic run / tui / tail HTTP + SSE alembic serve / cockpit MCP (read-only) POST /runs/:id/mcp HarnessCore neutro de transporte start · poll · fanout · report EventBus emite eventos (SSE) council (deliberação) runDebate + verifyDecision swarm (execução) partition + runSwarm (lead→workers)
Leia de cima para baixo: três transportes → um core único → council (delibera) e swarm (executa). O EventBus transmite cada passo ao vivo. Forjar a venture "fábrica de petições" usa exatamente este caminho.
A wide concept illustration of a single central conductor's podium glowing warm copper, wired by three distinct cables to three control panels labelled by shape — a small terminal
A wide concept illustration of a single central conductor's podium glowing warm copper, wired by three distinc
Papo Técnico ⚙️ (pode pular) — "Neutro de transporte" significa que HarnessCore não importa nenhum transporte, não abre porta de rede e não formata saída. Trocar a CLI por um servidor web não muda o motor. Em packages/harness/src/core.ts, o método fanout roda o council antes do swarm de propósito: se o veredito for NO_GO, ele curto-circuita antes de despachar qualquer worker — "uma banca que não aprova não pode gerar trabalho autônomo".
4

Lead → workers: a distribuição


Quando uma tarefa carrega subtarefas, ela vira um lead. Em vez de fazer o trabalho sozinho, o lead lança as subtarefas para vários workers em paralelo. Mas ele não solta todos de uma vez: lança um punhado, espera um pouco, libera mais um — uma rajada controlada (ramp). Isso evita sobrecarregar o sistema.

depth 0 depth 1 depth 2 orchestrator lead (subtasks) worker worker worker worker MAX_DEPTH = 2 · um worker é folha: NÃO pode gerar ninguém
Três papéis, profundidade limitada. O orquestrador pode gerar leads; um lead pode gerar workers; um worker é folha. O teto é estrutural (no schema) e verificado em runtime (canSpawn).

A rajada controlada (ramp)

O ramp tem três números: começa lançando 5 de imediato (initialLimit), libera +1 a cada 700 ms (intervalMs), até o teto maxConcurrency. É o "padrão Kimi" de subir devagar.

0 5 teto tempo (cada degrau = 700 ms) → 5 imediatos +1 por tick até o teto
A concorrência permitida sobe em degraus. Tarefas que terminam não abrem vaga — o ramp controla o total lançado ao longo do tempo, não o número em voo.

Como um worker entrega: filesystem como IPC

Um worker não fala com o orquestrador por um canal de memória. Ele escreve um arquivo. Primeiro grava o relatório em <id>.report.md (em progresso); quando termina, renomeia para <id>.complete.md (deu certo) ou <id>.failed.md (falhou). O orquestrador só observa os nomes finais.

worker escreve <id>.report.md rename() exit 0 → <id>.complete.md erro → <id>.failed.md orquestrador observa só os nomes finais
O rename() é o "commit": atômico. O orquestrador nunca vê um relatório pela metade — e o trabalho sobrevive à morte do processo, coisa que um canal em memória não faria. Um --resume reanexa ao relatório em vez de refazer o trabalho.
canal em memória filesystem como IPC ✗ morre se o processo cai ✗ nada para reanexar ✗ um observador novo perde o histórico ✓ relatório persiste em disco ✓ --resume reanexa ao relatório ✓ journal append-only = replay
O custo é um pouco de IO; o ganho é durabilidade e retomada. Por isso o swarm escreve arquivos em vez de usar um canal em memória.
cada transição events.jsonl (seq++) checkpoint.json estado reconstruível replay / --resume último checkpoint + eventos o filesystem é a fonte da verdade — toda linha re-validada por Zod na leitura
A run é resumível: o replay parte do último checkpoint e aplica os eventos seguintes. Uma queda no meio não perde o progresso.
Dica 💡 — Existe ainda o modo background: true (padrão tac-9 /background): o worker roda como processo destacado, então sobrevive mesmo se o orquestrador cair no meio. Útil para builds longos. Só vale para tarefas com command (não para chamadas a modelo).

Antes de revelar — adivinhe

Um lead tem maxConcurrency: 20. Cinco workers são lançados de imediato. Três deles terminam em 200 ms. Quantos workers o ramp permite lançar no total ao chegar em 700 ms?

Seis. Os 5 iniciais + 1 liberado no primeiro tick (700 ms). Os três que terminaram não abrem vaga: o ramp conta o total lançado ao longo do tempo, não os em voo. Esse é justamente o detalhe contraintuitivo de drainWithRamp.

5

Missões: units[] e proof[]


Você não escreve tarefas de swarm na mão. Você descreve uma missão: uma lista de unidades de trabalho (units), e para cada uma, uma lista de provas (proof) — comandos que precisam passar. O compilador transforma isso em tarefas de verdade.

packages/mission/src/compiler.ts — compileUnits()
# cada unit vira UMA tarefa de worker…
tasks.push(taskSpecSchema.parse({
  id: unit.id, title: unit.title, tier: unitTier,
  roleHint: 'worker', prompt: buildUnitPrompt(unit), ...
}));

# …e cada string de proof[] vira uma tarefa de COMANDO
# que depende da unit e falha fechado se sair != 0
for (const [index, proof] of unit.proof.entries()) {
  tasks.push(taskSpecSchema.parse({
    id: `${unit.id}-proof-${index}`,
    command: ['bash', '-c', proof],   // roda da raiz do repo
    dependsOn: [unit.id],             // só roda se a unit terminou
    metadata: { kind: 'proof', unitId: unit.id, proofIndex: index },
  }));
}

Para a venture "fábrica de petições", uma unit poderia ser "implementar o gerador de petição a partir do template do escritório", com proof: ['pnpm -r typecheck', 'pnpm -w test']. Se o teste reprovar, a prova falha — e a missão inteira falha fechado.

unit (a unidade de trabalho)

  • vira uma tarefa de worker
  • tem id, title, tier, prompt
  • pode declarar milestoneId, skillName, fulfills
  • é onde o trabalho de fato acontece

proof (a prova)

  • vira uma tarefa de comando bash -c
  • dependsOn a unit — só roda depois dela
  • exit 0 → complete; qualquer outro → failed
  • persistida em units/<id>/proof-results.jsonl
Cuidado ⚠️ — Armadilha de iniciante: achar que proof[] é "documentação" do que testar. Não é. Cada string é executada de verdade, da raiz do repo, e um exit diferente de zero derruba a run. Escreva provas que você realmente quer que travem o trabalho.
6

A esteira de cinco gates


Entre o trabalho e o "publicado", a peça passa por cinco porteiras em ordem. Cada uma tem um objetivo e o poder de travar. Pense em postos de inspeção: se um reprova, a peça não avança.

1 · Scope copia GOAL+plano 2 · Council GO / NO_GO 3 · Proof roda proof[] 4 · Validator council independente 5 · Publish gist + Pages falhou? a esteira PARA / faz PARK (NO_GO curto-circuita o swarm · proof != 0 derruba · T4 vai pro ledger)
Cinco porteiras, em ordem. As setas pontilhadas para baixo são o caminho do "falhou": travar ou estacionar (park), nunca empurrar adiante. É a versão executável do "falhar fechado".
A wide illustration of a workshop conveyor belt carrying a small glowing legal-document artifact left to right through five sequential stone inspection archways, each archway a che
A wide illustration of a workshop conveyor belt carrying a small glowing legal-document artifact left to right
council delibera veredito? GO / NO_GO GO swarm despacha NO_GO para — nenhum worker
O Council curto-circuita: NO_GO encerra a fase antes de qualquer worker.
tarefas da missão partitionByAutonomy autônomas → fan-out (workers) park (T4 / irrev.) legal · security t4-parked.jsonl espera humano executa já
Antes do fan-out, o core separa o que pode rodar do que precisa de um humano. "Na dúvida, estaciona."
GateArquivoO que verificaSe reprova
1 · Scopeforge/src/scope.tscopia GOAL.md + plano + contrato pro run-dirrun não inicia
2 · Councilmission/src/council-gate.tsGO/NO_GO pré-voo (opcional)NO_GO curto-circuita o swarm
3 · Proofcoda/src/proof.tsroda as proof[]; exit 0?devolve err → run falha fechado
4 · Validatorcoda/src/validator.tscouncil independente revê a evidênciaNO_GO/rejeitado → park
5 · Publishcoda/src/publish.tsação outward (curso, manifesto)sem aprovação → t4-parked.jsonl
Quem constrói pode validar o próprio trabalho?
Não. O Validator Gate roda um council independente. "Quem constrói não valida" — é regra, não estilo.
Por que o Council roda antes do swarm?
Para que um NO_GO curto-circuite antes de despachar qualquer worker. Banca que não aprova não gera trabalho.
O que acontece com trabalho T4 / irreversível?
Vai pro park (t4-parked.jsonl): nunca auto-executa, espera aprovação humana. "Na dúvida, estaciona."
Onde ficam os resultados das provas?
Em units/<id>/proof-results.jsonl — append-only, auditável, lido pelo Validator como evidência.
7

No código: o Proof Gate falha fechado


Aqui está o trecho real que torna "falhar fechado" concreto. O Proof Gate junta os resultados das provas; se qualquer uma falhou, ele devolve um erro — e quem chamou derruba a run.

packages/coda/src/proof.ts
# trecho real, não editado
const failed = results.filter((r) => r.outcome === 'failed');
if (failed.length > 0) {
  const summary = failed
    .map((f) => `unit=${f.unitId} index=${f.proofIndex} command="${f.command.join(' ')}"`)
    .join('; ');
  return err(new Error(`Proof Gate failed: ${summary}`));
}
return ok(results);

Acesse você mesmo

No repo: packages/coda/src/proof.ts (a função runProofGate). Ela lê os estados das tarefas do journal append-only (events.jsonl) — por isso sobrevive a sobrescritas de checkpoint quando várias chamadas runSwarm compartilham o mesmo store. O Validator depois lê proof-results.jsonl como evidência (readProofResults em validator.ts).

Fonte primária — leia o gate de verdade
packages/coda/src/proof.ts · packages/coda/src/validator.ts · packages/coda/src/publish.ts

Os três gates fail-closed em ~100 linhas cada. Todos devolvem Result<T, Error> — nunca lançam. É a cintura estreita da lição 1 aplicada à orquestração.

8

Três superfícies: run · serve · cockpit


O mesmo motor, três jeitos de operar. run executa uma missão no terminal. serve sobe um servidor HTTP+SSE (e o bind MCP read-only) para acionar e acompanhar runs por rede. cockpit é o painel web sobre os diretórios de run.

alembic run executa no terminal --goal --plan --yes --resume / --coordinated truth: o run-dir alembic serve servidor HTTP + SSE POST /runs (202) GET /runs/:id/status GET …/events (SSE) + POST …/mcp (read-only) alembic cockpit painel web sobre os run-dirs espelha o SSE no browser observabilidade
Mesmas quatro operações do core por baixo (start · poll · fanout · report). A CLI, o servidor e o painel são adaptadores finos — trocar a superfície não muda o motor.

O serve aceita um POST /runs com { phase:"run", goal, plan, yes } e responde na hora com um 202 (aceito) — a run roda em background, e você acompanha por GET /runs/:id/status ou pelo stream de eventos. O bind MCP é só-leitura: um assistente externo pode ler o andamento, mas nunca disparar trabalho.

Em packages/harness/src/server.ts: node:http puro, tabela ROUTES (POST /runs, GET /runs/:id/status, GET /runs/:id/events) + a rota especial POST /runs/:id/mcp que fala JSON-RPC (initialize / tools/list / tools/call). As ferramentas MCP são harness_status, harness_events, harness_lane (+ as run-scoped context_pack e artifact_read) — todas read-only: não há start/fanout por MCP, então um host não pode mutar a run. Erros JSON-RPC viajam no envelope, então o status HTTP é 200 para uma troca bem-formada.

cliente alembic serve run (background) POST /runs {goal,plan,yes} kick off (void) 202 snapshot (na hora) GET /runs/:id/status GET …/events (SSE, held-open) frames de evento ao vivo →
O serve responde 202 imediatamente e roda a run em background; você acompanha por status (pull) ou pelo stream SSE (push). A verdade dura segue no diretório da run.
PERMITE (read-only) BLOQUEIA (nada de escrita) harness_status harness_events · harness_lane context_pack (run-scoped) artifact_read (com guard) start (abrir fase) fanout (despachar workers) qualquer gasto / mutação aprovar / publicar
O bind MCP é só-leitura por design: um copiloto enxerga a run inteira, mas disparar trabalho ou gastar continua sendo decisão de quem opera.

CLI vs. servidor — quando usar?

run é para o operador no terminal (forjar a venture localmente, com --yes). serve é para acionar runs de fora e deixá-las rodando — o caso AFK, com observabilidade por SSE. Em ambos, a verdade dura mora no diretório da run.

Por que MCP só-leitura?

Para integrar com assistentes sem dar a eles o poder de gastar ou mutar. Um host MCP enxerga status, eventos e artefatos da run — perfeito para um copiloto — mas disparar trabalho continua sendo decisão de quem opera.

9

Exemplo guiado: forjar a "fábrica de petições"


Vamos seguir o signal pelo caminho inteiro, do comando à esteira.

  1. Escopo. O operador roda alembic run --goal GOAL.md --plan alembic.plan.ts --yes. O Scope Gate copia GOAL.md, o plano e o contrato para o diretório da run.
  2. Compilação. A missão (units como "gerador de petição", "tela de upload do template") é compilada: cada unit vira uma tarefa de worker; cada proof[] vira um bash -c que depende dela.
  3. Council (se ligado). A banca dá GO/NO_GO. NO_GO curto-circuita aqui — nenhum worker é despachado.
  4. Partição + fan-out. O core separa as tarefas em autônomas e parked (T4/irreversível vão pro ledger), e o lead distribui as autônomas aos workers em rajada.
  5. Proof Gate. Terminado o trabalho, as provas rodam. Se pnpm -w test reprova, o gate devolve err e a run falha fechado.
  6. Agora você: a venture passou no Proof, mas uma unit é marcada tier: 'T4' (publicar a landing do escritório). O que acontece com ela no fan-out — e em qual ledger ela aparece? (Dica: reveja a partição e o park.)
10

Experimente: o caminhante de gates


Clique Rodar a missão e veja o artefato da venture atravessar as cinco porteiras, uma de cada vez. Depois ligue a chave "injetar prova que falha" e rode de novo: o Proof Gate vai falhar fechado e a esteira para ali. É a teoria desta lição, executável.

1
Scope
copia GOAL + plano + contrato
aguardando
2
Council
GO / NO_GO pré-voo
aguardando
3
Proof
roda as proof[] — exit 0?
aguardando
4
Validator
council independente revê
aguardando
5
Publish
gist + Pages (ou park)
aguardando
// pronto. clique "Rodar a missão" para mandar o artefato da venture pela esteira.

Este é um modelo da lógica real: o Proof Gate de proof.ts devolve err quando uma prova sai != 0, e o fanout de core.ts faz o NO_GO do council curto-circuitar o swarm. Aqui você dispara essas duas travas com um clique.

Recapitulação em slides

Os seis pontos para levar. Use as setas ou os botões.

Os papéis

Orquestrador → lead → worker

Três papéis, profundidade limitada a 2. O orquestrador abre; o lead distribui; o worker é folha e não gera ninguém. Velocidade vem do paralelo.

orchleadworker

A entrega

Filesystem como IPC

Worker escreve .report.md e renomeia para .complete.md/.failed.md. O rename é o commit atômico — o trabalho sobrevive à morte do processo.

.report.mdrename.complete.md

A missão

units[] viram tarefas, proof[] viram travas

Cada unit é um worker; cada proof é um bash -c que depende dela. Exit != 0 derruba a run. Você descreve; o compilador monta.

unitworker taskproof: bash -c (dependsOn unit)

A esteira

Cinco gates, fail-closed

Scope → Council → Proof → Validator → Publish. Cada porteira libera ou trava. NO_GO curto-circuita o swarm; T4 vai pro park; prova reprovada derruba.

ScopeCouncilProofValidatrPublish

A independência

Quem constrói não valida

O Validator Gate roda um council independente sobre a evidência (as proof-results.jsonl). Fail-closed: só approved === true deixa emitir.

builderevidênciavalidator

A operação

Um motor, três superfícies

run (terminal) · serve (HTTP+SSE + MCP read-only) · cockpit (painel). O HarnessCore é neutro de transporte: a superfície muda, o motor não.

runservecockpitHarnessCore
1 / 6setas
A wide illustration of one lead foreman figure at a dispatch desk handing numbered work-tickets to several worker figures at separate benches arranged in a fan, a few tickets still
A wide illustration of one lead foreman figure at a dispatch desk handing numbered work-tickets to several wor

Prove você mesmo: o default de autonomia

O Alembic é conservador por padrão: o tier-default é T4 — ou seja, na ausência de configuração, o trabalho estaciona para um humano. Rode alembic status e confirme:

$ alembic status
# saída real, offline, $0 — RESOURCES.md
status: default tier T4
  phases: discover -> validate -> design -> plan -> build -> review -> ship
  stores (.alembic): 4 opportunity, 0 learnings

As sete fases (discover → validate → design → plan → build → review → ship) são o arco que toda venture percorre. O tier T4 default é a razão de tanto trabalho cair no park: a segurança vem ligada de fábrica.

As Dez armadilhas de iniciante (e como escapar)

  1. Achar que proof[] é comentário. Cada string roda de verdade e pode derrubar a run.
  2. Esperar que um worker gere outro worker. Worker é folha: MAX_DEPTH = 2.
  3. Confiar numa linha JSONL editada à mão. Tudo é re-validado por Zod na leitura.
  4. Pensar que tarefas que terminam abrem vaga no ramp. O ramp conta o total lançado no tempo, não os em voo.
  5. Deixar quem construiu validar. O Validator Gate é council independente — de propósito.
  6. Rodar o swarm sem o council na frente. NO_GO precisa curto-circuitar antes de despachar workers.
  7. Tratar T4 como "rodar depois". T4/irreversível vão pro park e exigem aprovação humana.
  8. Dar a um host MCP poder de mutar a run. O bind é read-only: status/eventos/artefatos, nunca start.
  9. Refazer trabalho ao dar --resume. O resume reanexa ao relatório existente — não re-executa.
  10. Esquecer que a verdade mora no run-dir. O HarnessCore expõe status; o diretório da run é a fonte durável.

Revisão — três perguntas

Recupere da memória antes de conferir. Cada opção explica por que acerta ou erra.

1. No fanout do harness, por que o council roda antes do swarm?

Não é sobre velocidade. A ordem existe por segurança, não por desempenho.
Isso. "Uma banca que não aprova não pode gerar trabalho autônomo" — o NO_GO para tudo antes do primeiro worker.
O swarm não consome o score do council; o que importa é o veredito GO/NO_GO como porteira.

2. Uma proof[] sai com código 1. O que acontece com a run?

Não há "aviso": exit != 0 é falha terminal para a prova. Nada segue.
O Proof Gate não faz retry da prova; ele agrega resultados e, se houver falha, derruba a run.
Exato. runProofGate filtra as falhas e devolve err(new Error('Proof Gate failed: …')) — fail-closed.

3. Um host MCP conectado a POST /runs/:id/mcp pode iniciar uma nova fase?

Correto. As ferramentas são harness_status/events/lane (+ context_pack/artifact_read) — não há start/fanout por MCP.
Não existe ferramenta harness_start. O bind expõe só leitura, por design de segurança.
Não há rota de escrita por MCP, com ou sem flag. Disparar trabalho continua sendo decisão de quem opera.
Você é o professor — pergunte: "como eu escreveria a missão da fábrica de petições com units[] e proof[] de verdade?" ou "o que o Validator faz diferente do Proof?"  ·  A seguir (0005): a venture vai precisar de alguém para operar o atendimento — a Iris, um AI Employee que compõe soul + skills + memória + connectors + agenda.