Capstone: a máquina inteira
Trinta lições adentro, você consegue segurar o sistema inteiro numa só vista. O Alembic é um motor que transforma fontes brutas em conhecimento validado e realimenta trabalho concluído de volta em si mesmo — um loop fechado. A fusão Hermes adicionou as peças que faltavam para tornar esse loop auto-aperfeiçoante: uma memória para gravar, uma passagem de aprendizado com gate para gravar através, e um curador para podar o que fica obsoleto. Este capstone desenha o circuito completo, costura todas as trinta lições num só mapa, lista o que foi entregue e o que está deliberadamente estacionado, e termina com um quiz transversal sobre tudo que você aprendeu. Sem fatos novos — só o quadro montado.
packages/hermes/src/index.ts, docs/alembic-hermes-fusion-matrix.md e docs/alembic-complete-map.md
Tudo nesta lição já foi visto antes — é a costura das trinta lições. Por que importa pra missão: é a prova de que o motor fecha o loop auto-aperfeiçoante, e o inventário honesto do que ainda falta.
- Desenhar de cabeça o loop
distillar → aprender → sedimentar → podare dizer onde mora o gate (ADR-0018). - Localizar cada uma das 30 lições, cada um dos 7 subsistemas e cada uma das 4 invariantes no mapa de ponta a ponta.
- Traçar um caso completo (um 429 dentro do swarm) pela cintura estreita até o veredito do orquestrador.
- Distinguir as quatro disposições da fusão (CLONE/ADAPT/MERGE/IGNORE) e nomear o que está estacionado vs ignorado (e por quê).
01 · O único loop que tudo serve
Comece pela ideia mais simples do curso inteiro, antes de qualquer caixa ou tipo. Pense numa destilaria: ela recebe matéria-prima bruta, separa o que presta, guarda o destilado num barril rotulado e descarta a borra. O Alembic faz o mesmo com conhecimento. Todo subsistema e invariante neste curso existe para fazer esse circuito girar com segurança: distillar → aprender → sedimentar → podar.
O loop como fluxograma — com o gate no centro
Agora a camada precisa. O circuito não é uma linha reta: é um anel com um losango de decisão no meio. Cada gravação proposta precisa passar pelo gate do Validator antes de virar memória. Siga as setas — o ramo NÃO é o que torna "aprende consigo mesmo" seguro em vez de uma catástrofe de feedback:
Note o losango dentro do anel. Essa é a pedra angular (ADR-0018): o loop é com gate de Validator, nunca auto-aplicar. Sem ele, um sistema auto-aperfeiçoante deriva sobre seus próprios outputs ruins. O gate é o que torna "aprende consigo mesmo" seguro em vez de uma catástrofe de feedback — exatamente a razão de a passagem de aprendizado ser um ADAPT, e não um CLONE (veremos na seção 09).
applied[], rejected[] ou failed[] — ela cai? Pense antes de revelar.
failed[]. O balde rejected[] é para o que o gate reprovou; applied[] é para o que entrou (inclusive um fato já existente, contado como sucesso no-op). failed[] existe precisamente para o caso "gate aprovou mas o store recusou" — aqui, acima do orçamento. Três baldes existem para manter esses três destinos distintos (Lição 08 / Lição 23). Se você chutou rejected[], confundiu "o gate disse não" com "o store disse não" — são eventos diferentes, e o curso separa os dois de propósito.Onde cada gravação proposta vai parar — os três baldes
Aquela predição merece um diagrama próprio. A passagem de aprendizado roteia cada proposta por duas perguntas em sequência — primeiro o gate, depois o store — e o resultado cai em exatamente um de três baldes. Siga os dois losangos:
02 · O mapa de ponta a ponta — as trinta lições numa vista
Aqui está a figura que costura tudo. Da esquerda para a direita, o conhecimento flui: fontes entram pelo funil; o harness roda missões através da cintura estreita e do swarm; os 7 subsistemas do @alembic/hermes fecham o anel; e os gates + as 4 invariantes envolvem tudo como trilhos de segurança. Cada caixa cita a lição onde você a estudou.
Use os botões para acender uma camada de cada vez — fluxo, subsistemas, ou os trilhos de segurança — e ver como ela se encaixa no todo:
Esse mapa é o curso inteiro em um quadro: as Lições 14–19 são o harness (cintura, funil, invariantes, gates, swarm); as Lições 07–13 são os sete subsistemas dentro do @alembic/hermes; e as Lições 24–28 são os trilhos de disciplina (ADRs, test-safety, proveniência, custo, determinismo) que cercam tudo. Se você consegue apontar, neste mapa, onde cada lição vive, você internalizou a arquitetura.
03 · As trinta lições numa só linha
Outra forma de segurar o curso inteiro: como um arco. As trinta lições não são uma lista aleatória — elas sobem em quatro partes, da fundação à síntese. Veja onde cada bloco vive, e como ele alimenta o próximo:
04 · O que foi entregue
As contagens são verificadas na fonte pela própria fundação do curso (Lição 01): o complete-map registrou 19 pacotes de workspace + 1 app em 415 testes, que cresceram para ~565 após o @alembic/hermes aterrissar — os mesmos 565 que o estudo de caso da Lição 06 verifica verdes com um pgrep vazio.
pgrep de processos órfãos vazio.| Subsistema | Disposição | O que dá ao loop | Lição |
|---|---|---|---|
| memory | CLONE | o store durável onde gravações sedimentam | 7 |
| learning | ADAPT | a passagem propose→dispose com gate — a pedra angular | 8 |
| curator | CLONE | poda active→stale→archived (nunca deleta) | 9 |
| clarify | CLONE | a superfície de pergunta do portão humano T4 | 10 |
| web | CLONE | search/extract sobre um backend injetado | 11 |
| skills | CLONE | memória procedural com disclosure progressivo | 12 |
| media | CLONE | transcribe/vision em nuvem sobre backends injetados | 13 |
As quatro disposições da fusão — o vocabulário do curso inteiro
Toda decisão de fusão neste curso usou um de quatro verbos. Eles aparecem na tabela de subsistemas (todos CLONE menos learning), na fronteira estacionada (MERGE), e na lista de ignorados (IGNORE). Fixe os quatro lado a lado — é a régua com que você lê a matriz inteira:
05 · Trace um caso de ponta a ponta (passo a passo → agora você)
A melhor prova de que você segura a máquina inteira é traçar um evento por ela. Pegue o caso mais instrutivo do curso: um modelo retorna 429 fundo na chamada de adapter de um worker do swarm. Onde isso vai parar? Primeiro veja o caminho num diagrama, depois siga os passos — e por fim um exercício é seu.
runWithGuards (Lição 14): o throw (ou o 429) não escapa — vira um resultado tipado.ModelRunFailure tipado. O resultado é { ok:false, retryable:true } — uma falha discriminada com a flag retryable, não uma exceção solta. É a invariante nunca-lança (ADR-0009).runSwarmSafe (Lição 16, invariante 1): mesmo que algo escapasse, a borda de orquestração o capturaria de novo.runWithGuards na cintura (nunca-lança) e runSwarmSafe na re-fronteira de orquestração. A run sobrevive; a lane se recupera ou é registrada.applied[]. O inédito de score alto entra normalmente. O fato já existente é um no-op de sucesso graças ao dedup — "reforce, não duplique" (Lição 08 / Lição 23) — então também conta como applied, não como failed nem rejected. Dica: failed só apareceria se o store recusasse (ex.: acima do orçamento, como na predição da seção 01); rejected só se o gate reprovasse o score.06 · Os trilhos de segurança — 4 invariantes, 5 gates, 5 tiers
O que envolve todo o mapa são os trilhos. Três famílias deles, cada uma estudada numa lição: as 4 invariantes (L16), a pipeline de 5 gates (L17) e os tiers de custo com seu default fail-closed (L27). Vamos vê-los em três figuras rápidas, porque é neles que mora a autonomia segura.
As 4 invariantes — o anel que envolve tudo
As quatro invariantes (Lição 16) cercam cada chamada do sistema. São o que garante que nenhum caminho de falha vire catástrofe:
A pipeline de 5 gates — cada veredito em sequência
Antes e durante uma run, cinco gates filtram o trabalho em ordem (Lição 17). O Proof Gate e o Validator Gate falham fechados; um non-zero exit derruba a run:
A escada de tiers — e por que o default é o mais alto
O roteamento de autonomia (Lição 27) usa o enum Tier de @alembic/contracts — exatamente cinco degraus, T0 a T4 (subindo de "silencioso autônomo" a "estacionado p/ humano"). A contra-intuição que vale fixar: o default é T4 — o mais alto, com gate humano — porque fail-closed manda o caso não-classificado negar, não escapar barato. E LOCAL não é um sexto degrau: é um marcador ortogonal de custo/privacidade (uma unidade pode ser T2 e LOCAL ao mesmo tempo):
07 · O que está deliberadamente estacionado (a fronteira)
Engenharia honesta nomeia o que não está pronto. A matriz de fusão marca várias capacidades como ainda-não-entregues — de propósito, com razões. Estacionado não é o mesmo que esquecido: está na matriz, com uma disposição e um motivo.
- Cliente MCP (MERGE no
@alembic/harness) — o Alembic é um servidor MCP (read-only) mas ainda não pode consumir servidores MCP externos. A matriz sinaliza isto como um MERGE de alto valor; o TS SDK o torna mais limpo que o original Python. Estacionado, não rejeitado. - O backfill completo do corpus — a ADR-0006 manda profundidade frontier sobre o corpus WIKI_LLM inteiro via o modelo mais barato acima de um piso. Esse backfill orçado de uma vez é um plano, não uma run concluída.
- Artefatos de Design + GTM — a Fase D (interfaces autênticas) e a Fase E (docs de produto/GTM) do plano de orquestração estão escopadas mas pendentes; o motor está construído, as superfícies de produto não (consistente com a ADR-0001: superfícies vivem em produtos, não no motor).
O ciclo de vida do "estacionado"
Por que estacionado é recuperável e um backlog vago não? Porque cada item estacionado carrega uma disposição na matriz — um verbo (MERGE, p.ex.) e uma razão datada. Esse é o caminho de volta:
08 · Estacionado vs ignorado — duas decisões diferentes
Há uma distinção que vale fixar: estacionado ≠ ignorado. Estacionado é "vamos fazer, ainda não" (recuperável, na matriz com disposição). Ignorado é "decidimos não fazer" (justificado, um IGNORE com razão). Ambos batem um backlog vago. Veja os dois lado a lado:
Um sistema que entrega tudo de uma vez não entrega nada bem. A fusão traçou uma fronteira apertada — os sete subsistemas que fecham o loop auto-aperfeiçoante — e explicitamente adiou o resto com razões datadas. Trabalho estacionado é recuperável (está na matriz com uma disposição); trabalho rejeitado é justificado (um IGNORE com uma razão). Ambos batem um backlog vago. É a doutrina de portfólio (ADR-0016) em miniatura: WIP limitado, tudo rastreado.
09 · O fio condutor: disciplina sobre capacidade
Se você levar uma ideia de trinta lições, leve esta: o poder do motor vem das suas restrições, não de contorná-las. Cada restrição remove uma classe de falha, e juntas elas deixam um sistema autônomo rodar sem um humano vigiando cada passo — que era o objetivo inteiro. Veja como cada disciplina mata uma falha específica:
Disciplina vs capacidade — o mesmo objetivo, duas filosofias
O curso inteiro defende uma aposta: para um sistema autônomo, disciplina bate capacidade do modelo. Veja a balança e, abaixo, a escolha em "Simples" e em "Técnico":
Result/never-throws (ADR-0009) na cintura e na re-fronteira do swarm; portas injetadas (FsPort/Clock/IdFactory) para determinismo e replay; defaults fail-closed (DEFAULT_TIER = T4, o budget guard) para negar o caso desconhecido; o gate do Validator (ADR-0018) contra deriva; e a VM de plano que proíbe relógio-de-parede/aleatório para um replay honesto. As Lições 24–28 são essa camada.Como isso se encaixa
Este capstone não é uma peça do motor — ele é a máquina inteira. Por isso "como se encaixa" aqui significa a coisa toda de ponta a ponta: as duas metades que você estudou separadas finalmente costuradas num só circuito. À esquerda, o loop de conhecimento (a destilaria: distillar → aprender → sedimentar → podar). À direita, a pipeline de uma run (scope → council → proof → validator → publish). Elas se tocam num ponto só: o gate do Validator é, ao mesmo tempo, o gate-4 da run e o losango do loop (a seção 01). Clique nos passos para acender o caminho completo, da fonte bruta de volta à próxima run:
O ponto de contato é o losango: o gate do Validator é a única caixa que pertence às duas metades ao mesmo tempo. É por isso que "rodar uma run" e "o motor aprender consigo mesmo" são, no fundo, o mesmo evento visto de dois ângulos.
Onde você está na metodologia
No mapa de sistema da metodologia interativa, este capstone vive no nó conceitual de método (ancorado em council, ao lado das Lições 03/20/21/29) — mas o que ele desenha é o grafo inteiro: as camadas L-1 ingestion → L0 contracts/etl → L1 adapters → L2 council → L3 swarm → L4 harness, mais o funil, os gates e o loop de aprendizado que sedimenta de volta no substrato. Se você consegue apontar, naquele mapa, onde cada uma das 30 lições mora, você internalizou a máquina. A página de metodologia é o mesmo circuito desta seção, clicável peça por peça; a de prática é o mesmo circuito executado de verdade num terminal.
- Lição 04 · O loop fechado — porque define o anel
distillar → aprender → sedimentar → podarque a metade esquerda do diagrama desenha. - Lição 17 · A pipeline de gates — porque é a metade direita (scope→council→proof→validator→publish), e o gate-4 é o ponto de contato entre as duas.
- Lição 19 · O swarm — porque é o que, dentro da run, executa o trabalho pela cintura estreita sem deixar uma falha derrubar o todo.
- Lição 15 · O funil — porque é o T0→T3 que transforma o corpus bruto nos Learnings que alimentam a próxima run.
- Lição 08 · reviewAndLearn — porque é a passagem propose→dispose que vive exatamente no losango compartilhado (ADR-0018).
Na prática
O capstone tem um runbook próprio: rodar a máquina inteira uma vez, de ponta a ponta, e observar cada peça aparecer no terminal. Abaixo está a sequência mínima — todos os comandos são reais (verbatim do playbook completo e do CLAUDE.md). Para cenários por subsistema (resumir uma run quebrada, retomar com --resume, o gate coordenado), o playbook de prática destrincha cada um.
1 · Materialize o escopo — alembic plan
Tudo começa com um escopo: o plan gera o GOAL.md, o contrato e o módulo alembic.plan.ts determinístico (sem Date.now()/Math.random() — a VM rejeita, L28).
$ alembic plan "Implementar um serviço HTTP mínimo" # plan: GOAL.md + validation-contract.md + alembic.plan.ts + plano.html escritos # plan: módulo de plano validado (determinístico, sem relógio-de-parede/aleatório)
2 · Rode a run de ponta a ponta — alembic run --yes
O run dispara a pipeline de gates (scope → council → proof → validator → publish) sobre o goal + o plano. --offline mantém o funil hermético em $0; --yes dispensa a confirmação interativa. (Para o passe multi-lente adicional da Lição 18, acrescente --coordinated.)
$ alembic run --goal GOAL.md --plan alembic.plan.ts --offline --yes # run: scope gate — GOAL/plano/contrato copiados para o run-dir # run: proof gate — proof[] verde (pnpm -r typecheck && pnpm -w test) # run: validator — scrutiny por marco: GO # run: run-a1b2c3d4 concluída (offline, $0)
3 · Observe a run — runs list · tui · tail
As três janelas de observabilidade do harness: lista, dashboard de terminal e o stream ao vivo de eventos.
$ alembic runs list # RUN-ID STATUS UNITS QUANDO # run-a1b2c3d4 completa 3/3 há 1 min $ alembic tui run-a1b2c3d4 # dashboard de terminal da run $ alembic tail run-a1b2c3d4 -f # segue events.jsonl ao vivo (Ctrl-C p/ sair)
4 · Gire o loop de conhecimento — distill --offline · status
A metade esquerda do diagrama: o funil destila o corpus em Learnings, e o status mostra o tier-default e as contagens dos stores append-only (o funil nunca apaga, só acrescenta).
$ alembic distill ./corpus --offline # distill: discover -> validate -> design -> plan -> build -> review # [T3 review ] verified-GO: 12 learning(s) sedimented # distill: complete (offline, $0) $ alembic status # status: default tier T4 # stores (.alembic): 38 opportunity, 12 learnings
5 · Prove o determinismo — alembic replay
O fecho do circuito: replay re-executa a mesma run a partir de events.jsonl + cache. Como o plano é determinístico (a VM proíbe relógio-de-parede/aleatório, L28), o replay é honesto — o resultado não muda.
$ alembic replay run-a1b2c3d4 # replay: re-executa de events.jsonl + cache # replay: resultado idêntico (determinístico) — run-a1b2c3d4
# ...) são ilustrativos do formato — os rótulos, contagens e ids exatos variam por versão e por corpus. O que não é incerto são os comandos e flags em si (todos do CLAUDE.md e do playbook de prática): plan, run --goal/--plan/--offline/--yes, runs list, tui, tail -f, distill --offline, status, replay.
pnpm -r typecheck && pnpm -r build && pnpm -w test. Esta é a mesma suíte (~565 testes) que a Lição 06 verifica com um pgrep de órfãos vazio.alembic plan "Implementar um serviço HTTP mínimo" e abra o GOAL.md + o alembic.plan.ts gerados — confira que o módulo de plano não tem Date.now()/Math.random().alembic run --goal GOAL.md --plan alembic.plan.ts --offline --yes. Anote o run-id que ele imprime.alembic runs list para ver o status; depois alembic tui <run-id> (dashboard) e/ou alembic tail <run-id> -f (stream de events.jsonl). Procure pelos vereditos de gate por marco no run-dir.alembic distill ./corpus --offline e então alembic status — confirme que as contagens dos stores append-only refletem o que sedimentou.alembic replay <run-id> e verifique que o resultado é idêntico. É o anel inteiro — escopo → run → observação → destilação → replay — numa só sessão. Para cada cenário a fundo, siga o playbook de prática.Fixe os conceitos do curso (flashcards)
Clique pra virar. Estes recuperam ideias de lições diferentes — tente lembrar a resposta antes de virar. Recuperação ativa, espaçada ao longo do curso, é o que fixa de verdade.
ModelRunFailure tipado (ok:false, retryable:true), nunca uma exceção — garantido por runWithGuards + runSwarmSafe. Degrada a lane, não a run.alembic.plan.ts não podem usar Date.now()/new Date()/Math.random(). Use um Clock/fábrica de ids injetados.Revisão cumulativa do curso — através de todas as lições
Este é o quiz transversal do curso inteiro: cada pergunta cruza várias lições. Responda de cabeça antes de clicar — as quatro opções têm tamanho parecido de propósito, sem pista pela forma.
retryable na cintura; o swarm reestabelece a fronteira nunca-lança com runSwarmSafe. O orquestrador só vê resultados discriminados uniformes — por isso a falha de um provedor degrada uma lane, não a run. a erra a invariante central: a cintura nunca deixa o throw escapar, então não há try/catch a fazer (e logging não garante nada). c inventa um "retry para sempre" — a flag retryable informa a política, não promete tentativas infinitas. d confunde camadas: resume/checkpoint é para retomar uma run, não para um 429 numa lane.MemoryStore está acima do orçamento. A mesma run então re-propõe um fato já na memória. Onde caem os dois?failed = gate aprovou mas store recusou (acima do orçamento). Um fato existente re-proposto é um sucesso no-op contado como applied — "reforce, não duplique" (L8/L23). Três baldes existem precisamente para manter isso distinto. a/b jogam os dois no mesmo balde, apagando justamente a distinção que os três baldes existem para preservar. c inverte tudo: o que o store recusa é failed (não rejected), e o duplicado é sucesso (applied), não falha.Date.now() no seu alembic.plan.ts para um id, depois roda a suíte via vitest puro com um teste que abre um socket. Duas coisas dão errado. Quais?Clock/fábrica de ids injetados), e test:safe — não vitest puro — é o que mata o grupo de workers + varre. A receita (L29) assa ambos em "pronto". a ignora as duas regras impostas. c erra o mecanismo: não é o lint que pega Date.now(), é a VM de plano em tempo de execução. d erra ao permitir Date.now() — a VM o rejeita; é exatamente a metade da pegadinha.AIAgent Python para fork; e, "mais importante", o princípio do portão de emissão). 0006 proíbe sedimento sem gate e 0009 proíbe lançar, então a única forma que sobra é a passagem com gate, baseada em portas — as restrições determinam o design (L24). a troca um motivo de design por velocidade de runtime, que não é o argumento. b é só metade: a indisponibilidade do source é citada, mas a ADR diz que o motivo "mais importante" é o portão de emissão. d inventa um requisito de UI que não existe.@alembic/hermes fecham o anel, e a próxima run lê a memória + skills atualizadas. b embaralha a ordem e nega o anel — o ponto inteiro é realimentar. c põe os subsistemas antes do corpus, invertendo o fluxo. d apaga o funil, o swarm e os subsistemas — quase tudo que o curso ensina.Para onde ir depois
Você agora consegue ler qualquer subsistema @alembic/hermes e prever sua forma antes de abri-lo; traçar uma chamada de modelo pela cintura e um corpus pelo funil; defender todo veredicto de fusão; diagnosticar um vazamento de worker órfão; e seguir a receita para adicionar um subsistema próprio. A fronteira estacionada — o cliente MCP, o backfill do corpus, as superfícies de design e GTM — é o trabalho seguinte natural, e a matriz já diz como abordar cada um. O loop está construído; fazê-lo girar mais rápido e mais largo é a estrada à frente.
packages/hermes/src/ e ler um subsistema de ponta a ponta; você vai achar que ele lê exatamente como você agora espera.