Passo 7 · Alembic Completo · Playbook do operador · invariantes, checklists e labs
Alembic Completo · currículo fonte-de-verdade · Visual Course

Playbook do operador

As lições anteriores ensinaram como cada camada (L0→L4) funciona. Esta ensina como operar e evoluir o sistema sem quebrar as garantias dele: os 6 invariantes load-bearing que o Reviewer caça, um checklist por role (Engineer / Architect / Operator / GTM) e 6 practice labs que tocam superfícies reais do repositório.

Leia primeiro (fonte deste material)
Operator Playbook + Practice Labs · Evidence Inventory + Source Map (Fase 1/4 do learn-alembic-complete)

Tudo aqui é destilado de leitura direta das camadas L0–L4 e de .factory/CODING_STANDARDS.md. Cada invariante traz uma âncora arquivo:linha na seção Source Anchors. Nada é inventado: se um número não estava na fonte, ele não está aqui.

Leia a versão simples, ou abra a camada técnica em qualquer seção.
O que você vai conseguir fazer
  • Nomear os 6 invariantes de arquitetura e explicar por que cada um é load-bearing — não "boa prática opcional".
  • Aplicar o checklist da sua role (Engineer, Architect, Operator ou GTM) antes de tocar o sistema.
  • Rodar a sequência fail-closed de 4 gates antes de qualquer run real e ler o que cada gate prova.
  • Executar pelo menos um dos 6 labs e capturar a prova de que o invariante exercitado se manteve intacto.
Suposições tolas (o que presumimos de você — bem pouco)
  • Você já viu as lições de camada (L0 Contracts/ETL até L4 Harness) ou pelo menos sabe que o Alembic é um monorepo em camadas.
  • Você sabe abrir um terminal e rodar um comando pnpm. Não precisa decorar nada — os comandos estão todos aqui.
  • Você não precisa ser o autor do código. Este playbook existe justamente para quem opera sem ter escrito cada linha.
1

A grande ideia


Saber pilotar um avião não é o mesmo que saber a checklist de pré-voo. Os hot paths te ensinaram a pilotar cada sistema; este playbook é a checklist que impede você de decolar com o trem de pouso travado.

Os deep dives por camada ensinam como o sistema funciona. Este playbook ensina como operar e evoluir o sistema sem quebrar suas garantias fundamentais. Ele cruza todas as camadas com os invariantes que realmente importam em produção. Qualquer pessoa que queira contribuir, rodar o Factory em escala ou fazer manutenção de longo prazo precisa internalizar estes 6 invariantes e os labs práticos — porque mesmo quem domina as camadas individualmente pode causar regressões graves se ignorar as regras de quem opera.

Pense como… a diferença entre saber dirigir e saber fazer a revisão do carro sem furar o motor: a primeira faz o carro andar hoje; a segunda mantém o carro inteiro por anos. O playbook é a "memória institucional viva" do que não se pode quebrar — para que o conhecimento tácito não se perca com a rotatividade de pessoas ou agentes.

Por baixo do capô

O material-fonte é o cruzamento de dois estúdios do learn-alembic-complete: o Evidence Inventory + Source Map (Fase 1 — inventário de 235 arquivos .ts em packages/*/src + apps/cli, 7 pacotes @alembic/*, 4 gates obrigatórios) e o Operator Playbook + Practice Labs (Fase 4 — invariantes, checklists, labs). Os 6 invariantes abaixo são exatamente "o que o Reviewer caça ativamente" no fluxo ADW da .factory/.

Por que tratar isto como código de primeira classe? Porque o Alembic pretende evoluir a si mesmo de forma autônoma (o ADW da .factory/run.ts roda sobre o próprio engine). Um sistema que se auto-modifica não pode depender de "tribal knowledge": as invariantes precisam estar escritas, ancoradas em arquivo:linha e verificáveis por gate.

a escala da fonte deste playbook (Evidence Inventory, Fase 1) 235arquivos .ts 7pacotes @alembic/* 4gates obrigatórios
Os números vêm direto do inventário-fonte (235 .ts, 7 pacotes, 4 gates) — escala que justifica um playbook escrito.
dois tipos de conhecimento — o playbook é o segundo Hot paths (lições 1–6) → COMO cada camada funciona → fluxo de dados L0 → L4 → onde o request vira ship teórico: ensina a pilotar Playbook (esta lição) → COMO operar sem quebrar → os 6 invariantes load-bearing → checklist por role + labs operacional: ensina a não furar o motor
O SVG separa os dois conhecimentos — saber pilotar (hot paths) ≠ saber a checklist de pré-voo (playbook).
Infográfico warm-neutral 'Os 6 invariantes load-bearing do Alembic' em duas fileiras de três cartões numerados que partem de uma espinha dorsal central: The Waist (L1) com ModelAdapter.run -> Result e selo nunca-lança; Never-throws com Result<T>; Zod-first com 'o schema é a spec'; No upward deps com seta acíclica L-1 a L4; Filesystem-as-truth com JSONL append-only content-addressed; Fail-closed gates com selos PII redigido e budget checado; legenda de cores e rodapé 'verde no typecheck não basta'.

Mapa de uma olhada: os 6 invariantes que o Reviewer caça — leia da esquerda para a direita, fileira de cima e depois a de baixo.

Faça sua aposta antes de seguir

O código compila (pnpm typecheck passa), os testes passam, mas o seu novo adapter lança uma exception quando o gateway cai, em vez de devolver err. Isso é defeito ou é aceitável?

É defeito arquitetural — mesmo com tudo verde. O invariante never-throws (a cintura L1) diz que toda chamada de modelo retorna Result e nunca lança. "Compila e os testes passam" não é prova suficiente: a garantia é estrutural, e quebrá-la é defeito ainda que o código rode.

2

Os 6 invariantes de arquitetura


Estes seis são load-bearing: são exatamente o que o Reviewer caça ativamente. Quebrar qualquer um é defeito, mesmo que o typecheck passe. Comece pelo mapa de uma linha; cada cartão abaixo detalha o invariante e mostra a âncora arquivo:linha.

1 · Waist (L1)nunca lança 2 · Never-throwsResult<T> 3 · Zod-firstschema = spec 4 · No upward depsgrafo acíclico 5 · FS-as-truthappend-only 6 · Fail-closed gatesPII + budget Estes 6 são caçados ativamente pelo Reviewer. Quebrar qualquer um = defeito.
A faixa de invariantes — terracota = cintura/contratos; oliva = grafo, stores e gates. (Recriado fielmente do SVG da fonte.)

1 · The Waist (cintura, L1)

Toda chamada de modelo passa por ModelAdapter.run() e retorna ModelRunResult (discriminado em ok). Ela NUNCA lança. Essa única fronteira é a "cintura estreita" do sistema: o ponto por onde todo modelo entra.

a cintura: tudo entra por um ponto e sai como Result council swarm / worker harness / cli ModelAdapter.run()a cintura — nunca lança { ok:true, … } { ok:false, error }
Falha não é exception: vira o ramo ok:false do mesmo Result. Ver model.ts:30 + adapter-core.ts:23.

2 · Never-throws / Result<T>

Toda operação falível retorna Result, não uma exception. O helper tryCatchAsync embrulha o que poderia lançar e devolve um Result. A falha vira dado que o chamador inspeciona — nunca um throw que sobe a pilha sem aviso.

// o contrato: falha é um valor, não um throw (packages/contracts/src/result.ts:20)
type Result<T, E = Error> = { ok: true; value: T } | { ok: false; error: E };

const r = await tryCatchAsync(() => algoQuePodeFalhar());
if (!r.ok) return r;        // propaga o err — sem try/catch espalhado
usar(r.value);                // só aqui o sucesso é garantido
duas formas de tratar falha — o Alembic só aceita a da direita throw (proibido) erro sobe a pilha sem aviso o run morre de forma opaca Result (o jeito Alembic) falha vira { ok:false, error } o chamador inspeciona o valor
Never-throws: a falha deixa de ser um evento que escapa e vira um dado que o chamador trata.

3 · Zod-first contracts

Todo tipo importante é um schema Zod. O schema é a spec: valida na borda, gera o tipo TypeScript e documenta o formato num só lugar (packages/contracts/src/). Não há "tipo de um lado, validação de outro" — é a mesma fonte de verdade.

um schema, três usos — uma só fonte de verdade schema Zodcontracts/src/ valida na borda gera o tipo TS documenta o formato
Zod-first: validação, tipo e doc saem do mesmo schema — nunca de fontes que divergem.

4 · No upward dependencies

O grafo de camadas é acíclico: L-1 → L0 → L1 → L2 → L3 → L4, com contracts como vocabulário compartilhado por todos. Uma camada nunca importa de uma camada acima dela. É isso que mantém o sistema componível e testável.

dependências só descem o grafo — nunca sobem L-1 Ingest L0 ETL L1 Adapters L2 Council L3 Swarm L4 Harness upward dep = proibida
A seta de volta (L4→L0) está riscada: importar "para cima" quebra o invariante nº 4. Ver .factory/CODING_STANDARDS.md:16.

5 · Filesystem-as-truth

Os stores são append-only e content-addressed (JSONL). Isso dá a propriedade que define o sistema: re-run converge — rodar de novo não duplica registros, porque o conteúdo é endereçado pelo próprio hash. O disco é a verdade; a memória é só cache.

content-addressed: o mesmo conteúdo → o mesmo hash → não duplica run 1 · registro X run 2 · registro X sha(conteúdo) grava 1× (run 1) dedupe (run 2)
Filesystem-as-truth: o segundo run reconhece o hash e deduplica — o ledger só cresce na primeira vez.

6 · Safety gates são fail-closed

PII é redigido antes de qualquer adapter ou emit; toda chamada paga é budget-checked antes de rodar. "Fail-closed" significa: na dúvida, o gate recusa. assertRedactedForEmit bloqueia um emit não redigido; o budget guard degrada o tier antes de gastar demais.

fail-closed: a porta começa fechada e só abre com prova emit / chamada paga gate? redigido / dentro do budget libera na dúvida → bloqueia
O gate é uma porta normalmente fechada: abre só com prova; sem prova, recusa. Esse é o "closed" de fail-closed.
O fio que une os seis: nenhum deles é capturado por "o código compila". São propriedades de comportamento e de estrutura — por isso precisam de gates dedicados (seção 6) e de um Reviewer que os procure de propósito.
Invariante 1
O que a cintura (Waist, L1) garante sobre toda chamada de modelo?
clique para virar
Passa por ModelAdapter.run(), retorna ModelRunResult discriminado em ok e nunca lança.
Invariante 3
No Alembic, qual é a relação entre o schema Zod e a spec?
clique para virar
O schema é a spec: valida na borda, gera o tipo e documenta o formato num só lugar (contracts/src/).
Invariante 5
Que propriedade os stores append-only + content-addressed dão ao sistema?
clique para virar
Re-run converge: rodar de novo não duplica registros, porque o conteúdo é endereçado pelo hash.
Invariante 6
O que "fail-closed" quer dizer para os gates de PII e budget?
clique para virar
Na dúvida, o gate recusa: PII redigido antes do emit; chamada paga budget-checked antes de rodar.
3

Por que "load-bearing", não "boa prática"


A confusão mais comum é achar que os invariantes são "boas práticas opcionais". Não são. Eles são load-bearing — sustentam o sistema. Quebrar qualquer um (especialmente o never-throws da cintura ou os fail-closed gates) é defeito arquitetural, mesmo que o código rode.

boa prática (opcional)

Se você ignora, o código fica menos elegante, mas funciona. Ninguém caça. Exemplo: um nome de variável feio.

load-bearing (invariante)

Se você ignora, a garantia some — mesmo com tudo verde. O Reviewer caça. Exemplo: um adapter que lança em vez de devolver err.

por que o nome importa: a viga sustenta o teto o sistema (telhado) Waist Gates FS-truth vigas = invariantes viga removida o teto inclina
Remover um invariante não é "menos elegante" — é a viga que sai e o teto que inclina. Daí "load-bearing".
Cuidado "Compila e os testes passam" não é prova de que um invariante se manteve. Um adapter pode passar no typecheck e ainda lançar em runtime quando o gateway cai. A prova de um invariante é comportamental — você a obtém rodando o lab correspondente (seção 5), não olhando o build.
InvarianteSe você quebra…Status
Waist / Never-throwsuma exception sobe a pilha sem ninguém tratar; o run morre de forma opacaload-bearing
Zod-firstdado inválido entra fundo no sistema antes de explodir longe da causaload-bearing
No upward depso grafo vira ciclo; build e teste isolado deixam de funcionarload-bearing
FS-as-truthre-run duplica registros; a convergência (re-rodar = idempotente) someload-bearing
Fail-closed gatesPII vaza para um adapter externo; ou uma chamada paga estoura o budgetload-bearing
4

Checklists por role


O mesmo conjunto de invariantes é protegido por quatro lentes. A sua role define qual ângulo você defende. Use o explorador abaixo: cada aba acende a camada que aquela role mais toca e mostra a checklist correspondente.

quatro responsabilidades, um único núcleo os 6invariantes Engineer Operator Architect GTM / Product
As quatro roles defendem o mesmo núcleo por ângulos diferentes — nenhuma é dona sozinha das garantias.
Infográfico warm-neutral 'Quatro lentes sobre o mesmo invariante' em quadrante 2x2 partindo de um hexágono central 'os 6 invariantes': Engineer (oliva) com preservar Result, tryCatchAsync, não enfraquecer gates; Architect (terracota) com grafo acíclico, stores append-only, mudar contracts atualiza consumidores; Operator (azul) com rodar os 4 gates, monitorar residue e custo, PII bloqueado é incidente; GTM (ferrugem) com claim barato-e-seguro só com evidência e demo offline-primeiro.

As quatro responsabilidades em volta do mesmo núcleo — cada role guarda o invariante por um ângulo.

engineer

Engineer — desenvolvimento diário

  • Toda mudança que toca um model call preserva o contrato Result (nunca throw).
  • Toda nova operação falível usa tryCatchAsync ou equivalente.
  • Os gates de PII e Budget nunca são enfraquecidos.
  • Commits atômicos + conventional (uma mudança lógica por commit).
L4 · Harness L3 · Swarm L2 · Council L1 · Adapters (cintura) L0 · ETL + gates

Engineer → acende a cintura (L1), onde vive o contrato Result.

Dica do operador A regra de ouro da role Operator é uma sequência só: antes de qualquer run real, rode os 4 gates. Se um falhar, não rode — conserte primeiro. É exatamente o que a seção 6 detalha.
5

Os 6 practice labs (toquem código real)


Saber os invariantes não basta; você precisa vê-los segurarem. Cada lab abaixo toca uma superfície real (packages/adapters, council, etl, harness, .factory/, apps/cli) e produz um artefato que prova o invariante. Onde der, use --dry-run / --offline.

Lab guiado — quebrar o PII gate (de propósito, em teste)
1
Em um teste, injete um sinal de canal privado sem redação direto no residue (sem passar pela redação normal).
2
Rode o funnel sobre esse residue.
3
Observe o report: t1PiiBlocked > 0. O assertRedactedForEmit recusou o emit — o gate segurou.
4
Agora você: repita olhando o número exato de t1PiiBlocked e anote em um learning-record qual invariante (nº 6, fail-closed) foi exercitado e como você confirmou que ele se manteve.
Fluxograma warm-neutral 'Lab: provocar o fail-closed do PII gate' com cinco nós: sinal de canal privado sem redação injetado no residue, roda o funnel, losango de decisão assertRedactedForEmit redigido?, ramo NÃO destacado em ferrugem 'BLOQUEADO emit recusado t1PiiBlocked++', ramo SIM apagado 'emit liberado', cartão de prova oliva 't1PiiBlocked > 0 = gate funcionou' e chip packages/etl/src/pii.ts.

O caminho fail-closed do lab de PII: o ramo "não redigido" leva ao bloqueio — e o bloqueio é a prova de sucesso.

#LabSuperfície realProva esperada
1Novo adapter simples (ex.: echo local). Registre via createAdapterRegistry e rode alembic distill ./corpus --offline.adapters/src/registry.tsadapter usado, custo = 0
2Forçar um T3 park. Marque uma task irreversible: true (ou tier T4) e rode um council T3.councilparkedTier no report + park ledger
3Quebrar o PII gate (em teste). Injete um sinal de canal privado sem redação e rode o funnel.etl/src/pii.tst1PiiBlocked > 0
4Tracer um run do Factory (ambiente controlado). Pare após o Planner e inspecione o JSON em <plan>..factory/run.tsworktrees criados ao continuar
5Simular budget exhaustion. Rode com budget muito baixo em T2 e observe o tier degradar.etl/src/budget.tst2BudgetBlocked no report
6Re-run convergente. Rode o mesmo distill offline duas vezes com o mesmo corpus.etl/src/stores.tsprocessed ledger só cresce na 1ª; stores não duplicam

Todos tocam código real em packages/adapters, packages/council, packages/etl, packages/harness, .factory/ e apps/cli.

lab 2 · forçar um T3 park task irreversible/T4 council parked → park ledger prova: parkedTier no report
Lab 2 — o T4 não roda sozinho: ele é estacionado para decisão humana.
lab 5 · budget exhaustion T2 (caro) budget baixo tier degrada t2BudgetBlocked no report prova: degradou antes de estourar o gasto
Lab 5 — o budget guard prefere degradar o tier a gastar além do limite.
Mapa lab → invariante: lab 1 exercita a cintura (1); lab 3 o fail-closed de PII (6); lab 5 o fail-closed de budget (6); lab 6 o filesystem-as-truth (5); lab 2 e 4 exercitam o fluxo fail-closed do council/Factory que protege os demais. Escolha um, rode, e prove.
6

Como verificar — os 4 gates fail-closed


Antes de qualquer run real, a role Operator roda a sequência completa de gates. Eles são fail-closed: se um falha, você não avança. Esta é a checklist de pré-voo do sistema.

4 gates em série — qualquer falha trava antes do run real typechecktipos batem build.d.ts gerados test284+ passam detect0 anti-patterns run realliberado um falhou → pare e conserte; não rode
A sequência de pré-voo do Operator. Falha em qualquer gate trava o run — fail-closed.
# a checklist de pré-voo do Operator (rode da raiz do repo)
pnpm typecheck   # os tipos batem em todos os pacotes
pnpm build       # dependentes enxergam os .d.ts novos
pnpm -w test     # 284+ passam
pnpm detect      # 0 anti-patterns em todo o docs/ (impeccable)

# para cada lab da seção 5: rode o comando e inspecione o artefato
# (residue, reports, worktrees, ledgers).

Sinais que viram incidente

incidente de segurança

Qualquer sinal de canal privado com t1PiiBlocked > 0 em produção. Investigue: por que algo não redigido chegou ao gate?

monitoramento contínuo

Acompanhe _alembic-residue.jsonl e o custo por tier. Picos inesperados são o primeiro sintoma de algo fora do trilho.

Guarde isto Para o GTM/Product: claims de "barato e seguro" só viram FACT quando suportados por evidência de runs reais (FunnelReport + ledger). E toda demo começa com corpus pequeno + --offline.
Você rodou os 4 gates e o pnpm -w test falhou em 1 teste. O que a disciplina fail-closed manda fazer?
(b). Fail-closed = na falha de qualquer gate, você não avança. "Só 1 falhou" não existe na pré-voo: um gate vermelho trava o run inteiro até ser consertado. (a) e (c) enfraquecem a garantia exatamente onde ela protege.
7

Source anchors (evidência direta)


Cada invariante aponta para um arquivo real. Use esta tabela para provar qualquer afirmação deste playbook lendo a fonte — a disciplina é: nada sem âncora.

a disciplina: nada sem âncora uma afirmação âncora arquivo:linha o arquivo-fonte real sem âncora → não é fato, é boato
A regra de evidência do curso inteiro: cada claim deve ser rastreável até um arquivo real — senão não entra.
Arquivo:linhaInvariante / conceito
packages/contracts/src/model.ts:30The Waist (ModelRunResult)
packages/adapters/src/adapter-core.ts:23Never-throws spine
packages/contracts/src/result.ts:20Padrão Result<T> (+ tryCatchAsync:60)
.factory/CODING_STANDARDS.md:16No upward dependencies
packages/etl/src/stores.tsFilesystem-as-truth
packages/etl/src/pii.tsFail-closed PII gate (assertRedactedForEmit)
packages/etl/src/budget.tsFail-closed Budget gate
packages/swarm/src/store.tsSwarm journal + park ledger
Nota As linhas (:30, :23, :20, :16) são as do material-fonte (HEAD de quando o inventário foi feito). Trate-as como ponto de partida da leitura, não como verdade eterna: confirme abrindo o arquivo no seu checkout.
8

Recapitulando


Avance os slides para fixar o playbook em seis ideias.

1 · o que é o playbook

Operar ≠ pilotar

Os hot paths ensinam como cada camada funciona. O playbook ensina como operar e evoluir sem quebrar as garantias. É a checklist de pré-voo do sistema.

i
2 · o coração

6 invariantes load-bearing

Waist · Never-throws · Zod-first · No upward deps · FS-as-truth · Fail-closed gates. O Reviewer caça cada um. Quebrar qualquer um = defeito.

ii
3 · a regra dura

"Compila" não é prova

Verde no typecheck e nos testes não garante um invariante. A garantia é estrutural — a prova é comportamental, vinda dos labs.

iii
4 · quem defende o quê

Quatro roles, um núcleo

Engineer preserva Result; Architect guarda o grafo acíclico; Operator roda os gates; GTM só vira claim em FACT com evidência real.

iv
5 · a prática

6 labs que provam

Cada lab toca código real e produz um artefato — t1PiiBlocked, parkedTier, t2BudgetBlocked, ledgers — que mostra o invariante segurando.

v
6 · pré-voo

4 gates, fail-closed

typecheck → build → test → detect. Um falhou? Pare e conserte. Só então o run real é liberado.

vi
slide 1 / 6 use
As cinco frases que um operador internaliza
  1. Toda chamada de modelo passa pela cintura e nunca lança — falha é Result ok:false.
  2. O schema Zod é a spec; dado inválido morre na borda, não fundo no sistema.
  3. Dependência só desce o grafo; subir é defeito que quebra build e teste isolado.
  4. Store é append-only + content-addressed; re-run converge, não duplica.
  5. Gate é fail-closed: na dúvida recusa — PII redigido e budget checado antes.
Em uma frase, para você mesmo: "Os invariantes são ____ (não opcionais); a minha role é ____; e a prova de que um invariante segurou vem de ____ (não do build)." Se você preenche as três lacunas, está pronto para o glossário visual.
9

Verifique seu entendimento


Três perguntas. A pontuação corre sozinha — responda todas para fechar a revisão.

Revisão cumulativa
1 · Por que os 6 invariantes são chamados de "load-bearing"?
(c). Load-bearing = sustentam o sistema, como uma viga. O Reviewer os caça ativamente e quebrá-los é defeito arquitetural — independente de o código compilar. (a) confunde com estilo opcional; (b) inventa uma condição de carga que não existe na fonte.
2 · No lab do PII gate, o que t1PiiBlocked > 0 significa?
(b). O bloqueio é a prova de sucesso: fail-closed significa recusar na dúvida. (a) inverte o sentido; (c) descreve o lab de budget (t2BudgetBlocked), não o de PII.
3 · A role Operator está prestes a fazer um run real e o pnpm detect acusou 1 anti-pattern. Qual a ação correta?
(a). Os 4 gates são fail-closed em série: qualquer um vermelho trava o run até ser consertado. (b) racionaliza pular um gate; (c) não tem relação — budget não compensa um anti-pattern.
Acertos: 0/3
Próximo passo (prática real): escolha um dos 6 labs, execute-o em ambiente controlado (use --dry-run/--offline onde der), capture o artefato gerado e anote num learning-record qual invariante foi exercitado e como você confirmou que ele se manteve intacto. Essa anotação é a sua prova — não o build verde.