Passo 6 · Alembic Completo · Hot paths · os caminhos quentes
Alembic Completo · currículo fonte-de-verdade · Visual Course

Hot paths · os caminhos quentes

As cinco camadas já foram apresentadas (L0→L4). Agora atravessamos o Alembic de ponta a ponta pelos três caminhos que ele percorre na vida real: destilar um corpus (distill → Funnel), decidir algo de alto risco (Council T3 + Verifier) e o engine melhorando a si mesmo (Factory ADW). São três trilhas distintas — mas, no fim, todas pisam nas mesmas quatro invariantes.

Leia primeiro (fontes primárias)
As três páginas linha-a-linha de origem: hotpath-cli-funnel, hotpath-council-t3, hotpath-factory-adw

Esta lição funde os três traçados num só passeio coerente. Cada passo aqui é ancorado em arquivo:linha real — commands.ts:63, funnel.ts:83, verifier.ts:84, .factory/run.ts:22 — nada é inventado. Onde o número de linha aparece, ele veio direto do código-fonte.

Leia a versão simples, ou abra a camada técnica em qualquer seção.
O que você vai conseguir fazer
  • Definir o que é um caminho quente (hot path) e por que vale entendê-los linha a linha.
  • Traçar o caminho da destilação: CLI → runFunnel → T0 → T1 (gate PII) → T2/T3 — e dizer por que só o resíduo chega aos modelos.
  • Explicar a separação Maker → Checker do Council T3 e por que o verifier é read-only com três lentes.
  • Descrever o loop ADW do Factory (Planner → Implementer → Reviewer → Publisher) e por que ele é o engine consumindo a si mesmo.
  • Nomear as quatro invariantes que os três caminhos compartilham — a verdadeira lição.
Suposições tolas (o que presumimos de você — bem pouco)
  • Você já passou pelas lições L0→L5 deste curso: Result, tier, adapter, council, swarm e harness já não são palavras novas.
  • Você sabe ler um pseudocódigo simples. Não precisa decorar TypeScript — traduzimos cada trecho.
  • Você não precisa ter rodado o Alembic ainda. Cada caminho termina com um "como verificar" que você pode tocar depois.
1

O que é um caminho quente


Um caminho quente (hot path) é uma rota de execução que o sistema percorre o tempo todo — não um canto raro do código, mas a trilha pela qual quase todo trabalho de verdade passa. Se você quer entender um sistema, não comece pelos casos exóticos: comece pelos caminhos quentes, porque é neles que as decisões de projeto realmente aparecem em ação.

Analogia: numa cozinha de restaurante, o "caminho quente" é o trajeto que todo prato faz: pedido → praça quente → empratamento → passe → mesa. Você pode ter um forno de pizza exótico no fundo, mas é o trajeto principal que define se a cozinha é confiável. No Alembic há exatamente três trajetos principais.
Guarde istoOs três caminhos quentes do Alembic são: (1) destilar corpus, (2) decidir alto risco no Council, (3) o Factory evoluindo o próprio código. Decore os três nomes — o resto da lição é só zoom em cada um.

Por que "linha a linha"

As páginas de origem deste material seguem o padrão 13-FLOWCHART + 04-CODE-UNDERSTANDING: cada estágio do caminho é amarrado a um arquivo:linha real. Isso evita o erro comum de "explicar arquitetura por slogan". Quando dizemos "o gate de PII roda antes do store", podemos apontar exatamente funnel.ts:243 (emitSafeSignal) — e você pode abrir o arquivo e conferir.

2

Os três num mapa


Antes de mergulhar em cada um, veja os três lado a lado. Repare que eles começam em lugares diferentes (um CLI, uma decisão, uma issue do GitHub) mas convergem para o mesmo conjunto de garantias.

Faça sua aposta antes de seguir

Dos três caminhos, qual é o único que sempre roda 100% do corpus e sempre custa $0?

O T0 do Caminho 1 (destilação). T0 é determinístico, roda antes de qualquer LLM, dedupe por SHA-256 e pontua em 6 eixos — tudo $0. Só o que ele roteia para o resíduo sobe para os tiers pagos (T1/T2/T3).
3

Caminho 1 · distill → Funnel T0–T3


Este é o caminho que todo usuário e todo job de factory toca quando quer transformar um corpus (transcripts, bookmarks, mensagens…) em sinais de negócio verificados. Ele começa no CLI, injeta os adapters, entra no runFunnel e desce por quatro estágios de funil — cada um mais caro e mais seletivo que o anterior.

Analogia: é um funil de mineração. T0 é a peneira grossa e barata que passa toneladas de cascalho; só as pedras promissoras (o resíduo) seguem para os processos caros de refino (T1, T2, T3). Você nunca manda todo o cascalho para o refino — seria caro e lento.
Infográfico do caminho quente 1: uma esteira de destilação com cinco estações — CLI runDistill, runFunnel, T0 determinístico $0, T1 gate de PII, T2/T3 budget+council — e três chips de invariante embaixo.

O caminho da destilação como esteira: CLI → Funnel → T0 → T1 (gate PII) → T2/T3. Só o resíduo do T0 chega aos tiers pagos.

O fluxo, estágio a estágio

Estágio crítico: o gate de PII roda antes do store

A confusão mais comum é achar que a redação de dados privados acontece "depois do modelo". Falso. Em funnel.ts:243, emitSafeSignal roda antes de qualquer escrita: canal privado → redige → assertRedactedForEmit → só então vira um BusinessSignal. Se o gate falhar, o sinal é descartado (fail-closed).

Por que só o resíduo sobe — e a escada de custo

T0 é o filtro massivo e barato. Apenas os itens que ele marca como routesToResidue chegam a T1/T2/T3. Por isso a maior parte do corpus nunca toca um modelo pago — e o custo só aparece nos tiers de cima.

Entrada do CLI — apps/cli/src/commands.ts

apps/cli/src/commands.ts:63
63|export const runDistill = async (args, deps) => {
68|  const readable = await assertCorpusReadable(args.corpus);
69|  if (!readable.ok) return err(...);
75|  const adapters = buildRegistry(args.offline);
83|  const report = await runFunnel(args.corpus, { adapters, budget, dataDir, fs: nodeFsPort });
95|  return ok(report);
}

Todo erro vira err() — nunca um throw. Essa é a cintura do sistema (contracts/src/result.ts). Quando offline: true, buildRegistry faz bind do adapter offline em todos os tiers via asDefault, garantindo um run hermético $0.

O gate de PII — packages/harness/src/funnel.ts

packages/harness/src/funnel.ts:243
243|const emitSafeSignal = (entry) => {
244|  if (!isPrivateChannel(...)) return ...
246|  const redacted = redactSignal(...);
247|  const gate = assertRedactedForEmit(redacted, channel);
248|  return gate.ok ? redacted.signal : undefined;  // fail-closed
}

Anotações-chave do caminho: commands.ts:68 (assertCorpusReadable via tryCatchAsync → Result), etl/src/pii.ts (redactSignal + gate antes de qualquer write), council/src/verifier-panel.ts (verifyPanel + quorum, preserva dissent).

Como verificar este caminho

pnpm build
node apps/cli/dist/index.js distill ./corpus --offline --json
# observe no FunnelReport: T0 sempre roda; T1/T2/T3 só tocam o resíduo;
# custo só em tiers pagos; nenhum sinal privado sem redação chega ao store.
No Caminho 1, em que momento a redação de PII acontece?
É a (b). O gate é anterior ao store e fail-closed: canal privado → redactSignalassertRedactedForEmit → só então vira BusinessSignal. Se o gate falha, o sinal é descartado.
4

Caminho 2 · Council T3 + Verifier Panel


Quando o sistema precisa tomar uma decisão de alto risco — vale a pena perseguir esta oportunidade? — ele não confia num único modelo. O Caminho 2 é o coração da decisão: um council debate (o maker) e, em seguida, um verifier independente checa (o checker) usando lentes determinísticas. O resultado é GO, PIVOT ou NO-GO — com o dissent preservado.

Analogia: é a diferença entre um aluno que entrega a prova e um corretor que confere a prova. Se o mesmo aluno se autocorrige, ele tende a confirmar os próprios erros. O Alembic separa quem propõe (debate) de quem verifica (verifier) de propósito — e o corretor só olha as respostas estruturadas, nunca a "redação bonita" do aluno.
Infográfico do caminho quente 2: bloco MAKER (debate) ligado a bloco CHECKER (verifier read-only), com três lentes — coherence, faithfulness, domain — e a faixa de decisão GO/PIVOT/NO-GO mais o selo MAX_LOOPS=3 → T4.

Maker → Checker: o debate propõe, o verifier read-only confere por três lentes e a decisão sai como GO / PIVOT / NO-GO (ou parked em T4).

O fluxo: do debate à escalada

As três lentes do painel

O painel não é "rodar o mesmo verifier três vezes". Cada lente tem claims e oráculos diferentes — isso dá diversidade de perspectiva. E há um veto: se uma lente dura falha em qualquer uma delas, o painel inteiro é rejeitado, mesmo com quorum.

O ponto que muda tudo: o verifier é 100% read-only. Ele aceita apenas o DebateResult + ContextPack e não pode chamar o modelo de novo. Os oráculos só olham evidência estruturada (votos, scores, spread, quorum) — o texto livre do maker nunca é usado como prova. É isso que faz dele um checker de verdade, e não "mais um LLM julgando".

Debate (maker) — packages/council/src/debate.ts

packages/council/src/debate.ts:108
108|const bound = bindMember(member, options.adapters);
130|const result = await boundMember.adapter.run(input);
147|const scores = parseAxisScores(result.text);
153|const vote = buildVote({ memberId, axes: scores.value, rationale: result.text });

Cada membro (incluindo o contrarian, por último) roda em paralelo. A resposta é parseada de forma tolerante — o sistema nunca confia no texto livre, só nos scores estruturados.

Verifier (checker) — packages/council/src/verifier.ts

packages/council/src/verifier.ts:84
84|export type ClaimOracle = (evidence: VerifierEvidence) => { proven: boolean; evidence: string };
// oráculos determinísticos sobre votos, scores, spread, quorum
// NUNCA lê o rationale em prosa do maker

Anotações-chave: verifier.ts:22 (read-only por arquitetura), verifier.ts:49 (MAX_LOOPS = 3 → T4), verifier-panel.ts:34 (preserve-dissent veto), verifier-panel.ts:40 (FAITHFULNESS_CONFIDENCE_FLOOR = 0.5). O quorum padrão do painel é DEFAULT_PANEL_QUORUM = 2.

Como verificar este caminho

# em um run T3 (via harness ou factory), inspecione o VerificationReport + LensReport:
# - verdict === 'verified'
# - provenCount / totalClaims por lente
# - parkedTier (se presente = T4)
# - hardClaimIds que falharam
Por que o verifier do Council é considerado um "checker de verdade"?
É a (c). O verifier aceita apenas DebateResult + ContextPack, nunca re-invoca um modelo e seus oráculos só olham votos/scores/spread/quorum. O texto livre do maker nunca conta como prova.
5

Caminho 3 · Factory ADW Loop


Este é o caminho mais meta do sistema: o próprio Alembic usando o engine para melhorar a si mesmo. O comando pnpm factory roda um loop ADW (Plan → Implement + Review em paralelo, em worktrees isolados → Publish PR) sobre issues do GitHub marcadas ready-for-agent, com sandboxes Docker e gates completos.

Analogia: é uma fábrica que constrói peças para a própria fábrica. O loop pega tarefas da fila (issues), monta cada uma numa bancada isolada (sandbox + worktree), só aceita a peça se ela passa no controle de qualidade (gates) e, no fim, propõe a melhoria — mas nunca a instala sozinha na linha principal (a branch main é protegida).
Infográfico do caminho quente 3: um anel de quatro estações — Planner, Implementer, Reviewer, Publisher — girando em loop, com etiqueta central pnpm factory for iteration e chips de guarda sobre gates e sandbox.

O loop ADW como anel: Planner → Implementer → Reviewer → Publisher, repetido por iteração, cada worker num sandbox isolado.

O anel do loop

Detalhe esperto: o Reviewer só roda se houve commits

O Implementer pode terminar sem produzir nada (a issue era inviável, ou os gates barraram tudo). Nesse caso, rodar o Reviewer seria desperdício. Por isso o loop só dispara o Reviewer quando result.commits.length > 0 — economia e qualidade.

Cuidado com a confusão"O Factory é só um script externo." Falso. Ele é cidadão de primeira classe do sistema: usa o mesmo harness, council, adapters e invariantes do engine de destilação. É a prova viva de que o motor é poderoso o bastante para se auto-melhorar — e a main nunca é mergeada automaticamente: o humano (ou o council T4) decide.

Entrada do loop — .factory/run.ts

.factory/run.ts:22
22|for (let iteration = 1; iteration <= MAX_ITERATIONS; iteration++) {
25|  const plan = await factory.run({ ... plan-prompt.md });
33|  const planMatch = plan.stdout.match(/<plan>(.*?)<\/plan>/);
152|  await factory.run({ ... merge-prompt.md });
168|}

O Planner lê issues GitHub com label ready-for-agent, constrói um grafo de dependência e emite só as não-bloqueadas em JSON dentro de <plan>.

Execução paralela com limite

.factory/run.ts:52
52|let running = 0;
68|const settled = await Promise.allSettled(
69|  issues.map(async (issue) => {
70|    await acquire();
72|    await using sandbox = await factory.createSandbox({...});
83|    const result = await sandbox.run({ implement-prompt.md ... });
95|    if (result.commits.length > 0) await sandbox.run({ review-prompt.md });

Anotações-chave: run.ts:72 (createSandbox + worktree + docker = isolamento), run.ts:95 (Reviewer só com commits), packages/factory/src/Orchestrator.ts (o motor genérico: Effect layers, streaming, timers, resume) e .factory/CODING_STANDARDS.md (a régua que o Reviewer usa). O Publisher (run.ts:153) apenas abre PRs — a main é protegida por ruleset.

Como verificar este caminho

# requer .factory/.env (ANTHROPIC_API_KEY + GH_TOKEN) e imagem Docker
pnpm factory
# observe: Planner emite <plan>; workers em sandboxes paralelas (MAX 4);
# commits só após gates (typecheck + build + test + impeccable);
# Reviewer adversarial; Publisher abre PRs (nunca força push em main).
Exemplo trabalhado — siga o caminho 3 mentalmente
1
O loop começa (run.ts:22). O Planner lê duas issues ready-for-agent; uma depende da outra, então só a livre entra no <plan>.
2
acquire() libera vaga; createSandbox cria um worktree + container. O Implementer roda TDD red-green-refactor com o CODING_STANDARDS.md.
3
Os gates rodam: typecheck → build → test → impeccable. Todos verdes → há commits. Como commits.length > 0, o Reviewer adversarial roda.
4
O Publisher abre um PR contra a main protegida. Nada é mergeado sozinho — fim da iteração; o loop tenta a próxima issue (agora desbloqueada).
5
Agora você: e se os gates falhassem no passo 3? Diga, em uma frase, por que o Reviewer não rodaria — e quem decide o destino da issue. (Dica: commits.length e a main protegida.)
6

O que os três têm em comum


Aqui está a lição de verdade. Três caminhos com objetivos completamente diferentes — destilar, decidir, evoluir — e ainda assim todos exercem as mesmas quatro invariantes. É essa repetição que torna o Alembic previsível.

A separação maker/checker se repete. Repare: o Caminho 2 separa quem propõe (debate) de quem verifica (verifier). O Caminho 3 faz o mesmo: o Implementer propõe, o Reviewer adversarial verifica. E o Caminho 1 separa o que é barato e determinístico (T0) do que é caro e julgado (T2/T3). É o mesmo princípio de projeto, três vezes.

O caminho 3 fecha o ciclo sobre os outros dois

Recapitulação em slides

A ideia central

Três trilhas, uma promessa

Os caminhos quentes são as rotas que o Alembic percorre o tempo todo. Entendê-los linha a linha é entender o sistema — porque é neles que o projeto vira ação.

Caminho 1 · destilação

CLI → Funnel → T0 → T1 → T2/T3

T0 roda 100% do corpus e é sempre $0. Só o resíduo sobe. O gate de PII (funnel.ts:243) roda antes do store, fail-closed.

Caminho 2 · decisão

Maker propõe, Checker confere

O debate é o maker; o verifier read-only é o checker. Três lentes (coherence, faithfulness, domain) com oráculos determinísticos. Hard failure → veto.

Caminho 2 · escalada

GO ≥ 7.0 · PIVOT ≥ 5.0 · senão NO-GO

Re-litigou demais? MAX_LOOPS = 3parkedTier = T4: o humano decide. O dissent é sempre preservado.

Caminho 3 · auto-melhoria

Planner → Implementer → Reviewer → Publisher

O engine consome a si mesmo. Cada worker num sandbox isolado; gates antes do commit; o Reviewer só roda se houve commits; a main é protegida.

A lição

As mesmas quatro invariantes

Result nunca lança · PII redigido antes do store · budget fail-closed · stores append-only. Três caminhos, uma promessa — é isso que torna o engine previsível.

1 / 6setas
caminho 1

distill → Funnel T0–T3

Transforma um corpus em sinais verificados. T0 determinístico filtra tudo; só o resíduo sobe para os tiers pagos.

commands.ts:63 · funnel.ts:83
Invariante central deste caminho
  • Gate de PII antes do store (fail-closed)
  • T0 sempre roda e é sempre $0
  • Custo só nos tiers pagos (BudgetGuard)
7

Recapitulando


Conceito
O que é um caminho quente?
clique para virar
A rota de execução que o sistema percorre o tempo todo — por onde quase todo trabalho passa e onde as invariantes são exercidas. O Alembic tem três.
Caminho 1
Por que só o resíduo sobe?
clique para virar
T0 é o filtro massivo e $0. Apenas o que ele marca como routesToResidue chega a T1/T2/T3 — os tiers pagos. Assim o custo só aparece em cima.
Caminho 1
Quando roda o gate de PII?
clique para virar
Antes de qualquer store, em emitSafeSignal (funnel.ts:243). Sem redação válida (assertRedactedForEmit), o sinal privado é descartado.
Caminho 2
Maker vs. Checker?
clique para virar
O debate propõe (maker); o verifier read-only confere (checker) com oráculos determinísticos. O verifier nunca re-chama o modelo nem usa o texto livre como prova.
Caminho 2
O que dispara o T4?
clique para virar
loopCount > MAX_LOOPS (= 3) → parkedTier = T4. Re-litigado demais, a decisão é parqueada para um humano. GO ≥ 7.0, PIVOT ≥ 5.0.
Caminho 3
Por que o Reviewer pode não rodar?
clique para virar
Ele só roda se result.commits.length > 0. Sem commits, não há o que revisar — economia e qualidade. E a main nunca é mergeada sozinha.
Em uma frase: três caminhos quentes (destilar, decidir, evoluir) percorrem as mesmas quatro invariantes — e essa repetição é o que torna o Alembic previsível.
8

Verifique


Responda sem rolar para cima. A pontuação aparece embaixo.

Revisão dos caminhos quentes
1 · Qual tier do Caminho 1 sempre executa e é sempre $0?
É a (b). T0 dedupe por SHA-256 e pontua em 6 eixos, tudo $0. Só o resíduo sobe para T1/T2/T3.
2 · Por que o painel do Council usa três lentes em vez de rodar o mesmo verifier três vezes?
É a (a). Coherence, faithfulness e domain checam coisas diferentes. Rodar o mesmo verifier 3× não traria essa diversidade. Uma lente dura falhando veta o painel.
3 · No Caminho 3, o que garante que a main não recebe código não revisado?
É a (c). Nada é mergeado automaticamente. Some isso aos gates antes do commit e ao Reviewer adversarial: três camadas de defesa.
4 · Qual princípio de projeto se repete nos três caminhos quentes?
É a (b). Maker/checker (debate vs verifier; Implementer vs Reviewer) e o barato-primeiro (T0 antes de T2/T3). Os stores, aliás, são append-only — nunca mutáveis.
Acertos: 0/4
Próximo passo natural: o Playbook do operador — como rodar, observar e intervir nesses caminhos na prática (resume, approve/reject, propose, cockpit). Você já tem o mapa; lá você pega o volante.