Passo 4 · Operação · Operação · O playbook do operador
Learn Alembic Complete v3 · Visual Course

O playbook do operador

A superfície inteira que você opera HOJE — 33 comandos top-level, 47 formas documentadas — organizada por domínio, cada domínio com custo real ($0 vs. gated), uma receita copy-paste provada e os gotchas que custaram caro.

Leia primeiro (fonte primária)
O USAGE exportado — apps/cli/src/index.ts:68

Toda a superfície vem de UMA constante exportada (export const USAGE). Esta lição organiza essas linhas por domínio; nenhum comando aqui foi inventado — e nenhum número foi digitado à mão (33/47 são derivados; ver a prova P7 na Trilha de provas).

launch-academy · 06-operator-playbook · s0
0
comandos CLI top-level
0
formas documentadas no USAGE
0
workspaces (27 packages + 1 app)
0
testes verdes (pré-#159; #159 soma +4)
Leia a versão simples, ou abra a camada técnica em qualquer seção.
1

A superfície em um mapa


O Alembic tem uma regra de ouro operacional: todo comando nasce $0. O default de qualquer forma é dry-run, preview, offline ou determinístico — e o efeito caro (rede, escrita, gasto pago) fica atrás de uma trava explícita (--online, --write, --approve --yes). Você pode explorar a superfície inteira sem medo.

Pense como… um cockpit de avião em modo simulador: todos os botões funcionam e mostram o que FARIAM, mas o motor só acende quando você vira a chave física (a trava). A analogia quebra num ponto: aqui existem várias chaves, uma por tipo de efeito — e algumas exigem duas mãos ao mesmo tempo.

alembic — 33 comandos top-level · 47 formas (USAGE, apps/cli/src/index.ts:68) FUNIL & CONHECIMENTO · 9 distill · ingest · status wiki-bridge · embed-index vision-index · search context-pack · course duas cadeias ADR-0002 · RAG read-path AI EMPLOYEES · 1 (6 formas) employee list · show connectors · explain run · schedule soul + skills + memória bindada AUTOMATIONS · 1 automation list · show automation run (PR #159) manifests PAUSED · sem daemon MEMÓRIA · 2 memory add|list import (--skills, --distill --online) 5 substores JSONL MARKETING · 1 (9 formas) marketing · discover client · video · ad environment · sheets validate · campaign dupla trava --approve E --yes RUNS & OBSERVAB. · 13 run (2 formas) · plan · forge runs · cockpit · serve · tui tail · propose · approve reject · replay · docs events.jsonl é a verdade CAPACIDADES · 6 embed · ocr · triage notes · doctor (--client-stack) · help offline default · $0 9 + 1 + 1 + 2 + 1 + 13 + 6 = 33 top-level · agrupamento didático desta lição
Os 33 comandos top-level em 7 domínios. As "formas" extras (47 no total) são variantes documentadas — ex.: run tem 2, marketing tem 9, employee tem 6.
Camada técnica
# a fonte da superfície (só leitura):
sed -n '68,196p' apps/cli/src/index.ts   # export const USAGE = [ ... ]
alembic help                             # imprime o mesmo USAGE
2

Domínio · Funil & conhecimento


O coração do produto: destilar um corpus em conhecimento acionável. Desde o ADR-0002 são duas cadeias de valor sobre o mesmo T0 determinístico — a cadeia de SIGNALS (--budget) e a cadeia de LEARNINGS (--learnings-budget), com budgets, stores e cadências separados. A rota de learnings produziu pela primeira vez na história em 06-07: 1.022 learnings únicos de Bookmarks.

ComandoO que fazCusto
distill <corpus>Funil noturno T0→T3; --learnings-budget liga a 2ª cadeia (ADR-0002)$0 com --offline budgets = metered
ingest <source>Puxa um caminho de corpus para o intake do funil$0
statusReporta o pipeline do funil e o default de autonomia$0
wiki-bridge <fam>1 linha bridge package.jsonl por pacote wiki (etl-excluded)$0
embed-index <fam>Índice de embeddings offline da família (append-only, dedupe)$0
vision-index <fam>Índice VLM das imagens dos pacotes$0 --online = MLX local
search "<q>" <fam>RAG read-path: cosseno determinístico sobre o índice; índice ausente = resultado vazio$0
context-pack <files>Pack de contexto em 8 camadas; --retrieve injeta chunks no L3 (opt-in, byte-idêntico sem)$0
course <corpus>Curso visual-teach byte-estável; --images gera 1 hero opt-in$0 --images = gated

Receita real: a learnings-run com o truque cpio

receita · a run que produziu os 1.022 learnings (forma provada em 06-07)
# 1) staging: SÓ os package.jsonl da família, preservando "Bookmarks/" como 1º segmento do path
cd ~/Documents/Resources
find Bookmarks -name package.jsonl | cpio -pdm /tmp/corpus-bkm

# 2) as duas cadeias com budgets SEPARADOS (ADR-0002) + store isolado da rota
alembic distill /tmp/corpus-bkm --learnings-budget <usd> --data-dir ~/.alembic-learnings-bkm

# 3) prova no boundary: a linha-resumo da rota + o store no disco
#    "learnings-route: N learnings, ..."  (apps/cli/src/commands.ts:421)
wc -l ~/.alembic-learnings-bkm/Skills/learning/learnings.jsonl
Gotchas do domínio (custaram caro)
  • family-prefix: a família vem do 1º SEGMENTO do path relativo ao corpus (packages/ingestion/src/family-adapter.ts:98). Aponte o distill no PAI de Resources — apontar na raiz da família dá Unknown ⇒ residue 0, em silêncio.
  • Symlinks são ignorados: o walkCorpus não segue symlinks — um corpus "montado" por links não entra. Daí o truque cpio (copia de verdade, preservando a árvore).
  • Sem --learnings-budget a 2ª cadeia nem existe: a run fica byte-idêntica (só signals; sem chave routes no --json). Exaurir um budget bloqueia SÓ aquela rota.
Camada técnica
# cadeia típica do wiki (tudo $0):
alembic wiki-bridge ~/Documents/Resources/Bookmarks
alembic distill ~/Documents/Resources --offline
alembic embed-index ~/Documents/Resources/Bookmarks
alembic search "narrow waist" Bookmarks --top-k 3
# retrieval opt-in no pack (sem --retrieve o pack é byte-idêntico):
alembic context-pack GOAL.md --retrieve "cintura estreita" --family Bookmarks --rerank mmr
3

Domínio · AI Employees


Um AI Employee compõe o que já existe: soul (identidade + modelPreferences) + skills (os playbooks INTEIROS entram no prompt via SkillStore) + memory binding (só substores bindados entram) + declarações de connector/schedule. São 43 employees em ~/.alembic/employees e 148 skills em ~/.hermes/skills.

FormaO que fazCusto
employee listLista os employees (id/nome/role/#skills/#connectors)$0
employee show <id>Definição completa + o prompt renderizado (soul + skills + connectors)$0
employee connectors <id>Seam A3: resolve declarados → wired vs. unwired (offline: TODOS unwired, honesto)$0
employee explain <id> --goalMapa dos 10 passos com tags observed/inferred/unknown (anti-fabricação estrutural)$0
employee run <id> --goal1 turno; default = preview do prompt exato; --online chama o modelo + write-back A3b$0 dry-run --online
employee schedule <id>schedule[] → manifests de automation (print; --out escreve PAUSED)$0

Receita real: o turno com dados-no-prompt

receita · o caveat de honestidade transformado em disciplina
# NUNCA: --goal "varra os arquivos de X e resuma" → o turno NÃO tem tool-loop;
#        a "varredura" sai FABRICADA (provado; ver P2 na Trilha de provas).
# SEMPRE: você coleta o dado verificado; o dado VAI NO PROMPT.
DADOS=$(cat ./relatorio-verificado.md)

# $0: preview do prompt exato que seria enviado (system + goal + modelId)
alembic employee run <id> --goal "Com base SÓ nos dados abaixo, priorize os 3 riscos: $DADOS"

# gated: chama o modelo E appenda 1 registro episódico HONESTO (goal real + excerpt real)
alembic employee run <id> --goal "Com base SÓ nos dados abaixo, priorize os 3 riscos: $DADOS" --online
Gotchas do domínio
  • Sem tool-loop no turno: pedir "varra X" produz varredura fabricada (provado). Dados verificados vão no prompt — até a perna tool-loop existir.
  • Só substore bindado entra: um store não-bindado nunca vaza para o prompt; o write-back A3b também é opt-in (sem binding episódico ⇒ no-op). --no-memory-write desliga; o dry-run NUNCA escreve (packages/hermes/src/employee/writeback.ts:74).
  • Skills entram INTEIRAS: os corpos viram a seção ## Skill Playbooks (packages/hermes/src/employee/run.ts:256) — o modelo segue as REGRAS da skill, não só vê os nomes.
  • O modelo vem do soul: modelPreferences.primary ?? fallback ?? local-default; a forma employee run do USAGE não documenta flag de modelo — pin no soul.
Camada técnica
alembic employee list
alembic employee show <id> --json
alembic employee connectors <id> --json     # {wired,unwired} — nunca dropado em silêncio
alembic employee explain <id> --goal "triagem diária" --json
4

Domínio · Automations


A4 liga employee → automation: cada schedule[i] vira UM manifest automation.toml com id determinístico emp-<id>-<i>, status PAUSED — registrável mas spend-safe, nunca roda sozinho. E o automation run (PR #159) executa um manifest À MÃO: dry-run por default; --online roda o turno e appenda 1 registro honesto ao journal memory.md. Não é um daemon.

FormaO que fazCusto
automation listLista manifests <id>/automation.toml sob --dir (default ~/.codex/automations)$0
automation show <id>Imprime um manifest em full (--json estruturado)$0
automation run <id> (PR #159)EXECUTA um manifest; --online = turno real + 1 registro no journal memory.md$0 dry-run --online

Receita real: o ciclo A4 em 4 comandos

receita · de declaração a execução manual, sem daemon novo
# 1) veja as declarações schedule[] do employee
alembic employee show <id>

# 2) materialize schedule[] → automation.toml (PAUSED; id determinístico emp-<id>-<i>)
alembic employee schedule <id> --out ~/.codex/automations

# 3) o registro lê o manifest de volta (mesmo path/subset-TOML)
alembic automation list --dir ~/.codex/automations

# 4) execute À MÃO (dry-run default; --online = turno + journal honesto)  [PR #159]
alembic automation run emp-<id>-0 --dir ~/.codex/automations
Gotchas do domínio
  • PAUSED nunca auto-roda: o A4 mapeia declarações; o daemon de cron é trabalho do pacote automation existente — nada novo foi construído.
  • O cron viaja opaco: a string cron vira o rrule do manifest sem interpretação; created_at/updated_at fixos em 0 (determinismo, sem clock).
  • O caveat do turno vale aqui também: a automation executa um turno de employee — sem tool-loop; prompts com "varra X" fabricam. Dados no prompt.
Camada técnica
alembic employee schedule <id> --json    # imprime os manifests sem escrever (spend-safe)
alembic automation show emp-<id>-0 --dir ~/.codex/automations --json
# mapper: apps/cli/src/employee-schedule.ts:111 (employeeToAutomations, puro/determinístico)
5

Domínio · Memória & import


A memória multi-store é JSONL append-only em <data-dir>/memory/<substore>.jsonl, com 5 substores: episodic · semantic · procedural · decision · transcript (packages/hermes/src/memory/multi-store/composer.ts:3). O import (A4b) traz sessões Claude/Codex/ChatGPT para o transcript — e, com --distill --online, destila semantic/decision marcados como interpretação de modelo, nunca como fato.

FormaO que fazCusto
memory <substore> add|listAppend/consulta no multi-store (filtra por --agent)$0
import <path>Sessões → transcript memory; ids determinísticos import-<sessão>-<n>; dedupe-by-id ⇒ idempotente$0 dry-run --write appenda
import --skills<name>/SKILL.md → SkillStore; colisão de nome = skip (idempotente)$0 dry-run --write cria
import --distill --onlineDestila sessão → semantic + decision via modelo local (DeepSeek); --write separa o persist--online gates o CALL · --write gates o WRITE

Receita rápida ($0, idempotente)

# preview: quantos records NOVOS uma sessão geraria (nada é escrito)
alembic import ~/.claude/projects/<sessão>.jsonl
# appenda só os novos; re-rodar é no-op (dedupe por id determinístico)
alembic import ~/.claude/projects/<sessão>.jsonl --write
alembic memory transcript list --limit 5
Gotchas do domínio
  • Interpretação NUNCA vira fato: todo record destilado carrega proveniência session:<id> + distilled:<modelId> e confidence ≤ 0.5; tags com essa forma vindas DO MODELO são removidas para ninguém falsificar origem (packages/hermes/src/memory/session-distill.ts:81,89).
  • --distill sem --online falha fechado: sem gasto, sem fabricação. E --online sem --write = preview dos would-write (persiste NADA).
  • SkillStore não segue symlinks: skills de plugin symlinkadas sob a base NÃO são importadas — só diretórios <name>/SKILL.md reais.
  • Escopo do --skills: importa SÓ o SKILL.md; references/, scripts/ etc. são follow-up anotado.
Camada técnica
alembic import <path> --distill --online          # computa e reporta; NÃO persiste
alembic import <path> --distill --online --write  # appenda semantic.jsonl + decision.jsonl
alembic memory semantic list --limit 3
alembic memory decision list --limit 3
# id destilado: distill-<agent>-<sessão>-sem|dec-<n> (o agent no id ⇒ 2º --agent não é dedupado)
6

Domínio · Marketing factory


Fábrica multi-tenant com modelos FIXOS — vídeo gemini_omni (pt-BR + lipsync), imagem gpt_image_2 — e identidade REAL do cliente injetada em cada cena (refs ROLED via API direta; provado com o escritório da C.D, em 3 indústrias). A regra que você nunca esquece: dupla trava — só gasta com --approve E --yes juntos.

FormaO que fazCusto
marketing <signal|brief>Sinal/brief → copy/GTM → criativos → manifest versionado$0 fake Higgsfield --online
marketing discoverRequest fino → ClientBrief rico (campos não aprendidos ficam no default)$0 --online = brightdata
marketing client <pasta>Pasta do cliente → brief de identidade (brand-profile curado; nunca inventado)$0 --online = upload refs
marketing video <shotlist>Cenas de anúncio; custo estimado PRIMEIRO; aspect viaja como PARAM$0 dry-run --approve --yes
marketing ad <pasta> <brief>Capstone: identidade real + shotlist de diretor + cenas multi-ref$0 dry-run --approve --yes
marketing environmentSheet do AMBIENTE real (ffmpeg extrai ângulos; $0 no core)$0 recreate = online
marketing sheetsSheets de personagem/produto/prop (locks universais)$0 plano --approve --yes
marketing validate <mp4>QA gate local: formato/transcript/marca/visuais — cada check é opt-in$0 seams --online ocr/vision
marketing campaignDiscover→generate→validate em um tiro; TODO estágio dry-run por default$0 --online / --approve --yes

Receita real: o ad em dry-run (e a dupla trava)

receita · capstone provado em 3 indústrias
# $0: ingest da pasta + shotlist do diretor + PREVIEW de custo por cena. NADA é gasto.
alembic marketing ad ./clientes/<pasta> brief.json --aspect 9:16

# gasto real SÓ com AS DUAS travas juntas (uma flag sozinha NUNCA gasta):
alembic marketing ad ./clientes/<pasta> brief.json --aspect 9:16 --approve --yes
launch-academy · 05-launch-gtm-marketing-seo · s1
Gotchas do domínio
  • Aspect é PARAM, não texto: escrever "9:16" no prompt é ignorado e o render sai 16:9 (o validate então REPROVA). Use --aspect — ele viaja como aspect_ratio de geração.
  • Refs no gemini_omni vão pela API direta: o --image plano do CLI é rejeitado; no caminho pago as refs reais entram como medias ROLED — foi assim que o escritório real da C.D apareceu (720×1280).
  • Pasta de cliente nunca é varrida às cegas: descoberta de assets é opt-in via --assets-dir (PII de casos fica fora por construção).
7

Domínio · Runs & observabilidade


Onde missões executam e onde você OLHA. A verdade de uma run mora no run-dir (events.jsonl + cache); tudo aqui ou dispara uma run ou lê esse registro. T4 nunca executa sozinho: parkeia e espera approve/reject/propose.

ComandoO que fazCusto
run <spec> · run --goal --planMission/tasks OU escopo Forge; --offline herm.; --coordinated aditivo$0 com --offline tiers/budget
plan "<prompt>"Plano HTML + GOAL.md + contrato + alembic.plan.ts$0
runs listRuns persistidas sob --data-dir$0
cockpit · serveDashboard web · servidor HTTP+SSE stateful$0
tui <run-id> · tail <run-id> [-f]UI ASCII ao vivo · stream de eventos recentes$0
propose · approve · rejectCiclo T4: reabre parked / registra aprovação / registra rejeição$0
replay <run-id>Re-executa de events.jsonl + cache$0 do cache
forge <course-dir> · docs <src> <out>Publish gate de curso · site HTML de Markdown$0 local

Receita rápida: disparar e observar

alembic run --goal GOAL.md --plan alembic.plan.ts --yes
alembic runs list
alembic tail <run-id> -f      # segue os eventos ao vivo
alembic tui <run-id>          # mesma verdade, em painel
Gotchas do domínio
  • Empate de custo = ordem de declaração: pickCheapestForTier usa < estrito e mantém o PRIMEIRO declarado no empate (packages/contracts/src/registry.ts:244; comentário nas linhas 80–83). Foi o que o PR #157 explorou no empate T2 de 0.0005.
  • --resume valida o trio: goal/plan/contract são conferidos contra meta.json; mudou o plano, não é a mesma run.
  • Determinismo no plano: Date.now()/new Date()/Math.random() em alembic.plan.ts = a VM rejeita.
8

Domínio · Capacidades atômicas


Primitivas de bolso — todas offline/determinísticas por default, todas com --online opt-in para o backend real. São os mesmos kernels que os domínios grandes usam por dentro.

ComandoO que fazCusto
embed "<texto>"Vetores offline $0 (--json = vetores completos)$0 --online
ocr <imagem>Texto determinístico offline; real precisa de setup$0 --online
triage "<issue>"Classificação de issue (template hermes)$0 --online
notes <transcript>Notas de reunião; data default do clock do CLI$0 --online
doctor · doctor --client-stackPrereqs de ambiente · registry+adapters SEM rede; --online = smoke por modelo, fail-closed$0 --online
helpImprime o USAGE (a fonte deste playbook)$0

Receita rápida: o check-up de 30 segundos

alembic doctor --client-stack          # registry + coerência de adapters, $0, SEM rede
alembic embed "cintura estreita"       # prova o caminho de embeddings offline
alembic triage "botão de login quebrado no Safari"   # classificação determinística
9

O fluxo dry-run → gated


Repare no padrão que atravessa TODOS os domínios: o default mostra o que aconteceria; cada tipo de efeito tem a sua trava. Chamada de modelo? --online. Persistência? --write. Dinheiro de verdade? --approve E --yes — juntos.

qualquer comando DEFAULT $0 dry-run · preview offline · determinístico trava --online chamada de modelo/rede trava --write persistência (append) --approve E --yes gasto pago (as DUAS juntas) EFEITO REAL turno · registro · render exemplos: employee run … --online import --distill --online --write marketing ad … --approve --yes uma flag sozinha NUNCA gasta · falha fechada = sem gateway/token ⇒ erro ANTES de gastar
O contrato operacional: default $0 → trava explícita por tipo de efeito → efeito real. O gasto pago exige as duas travas ao mesmo tempo.
Você roda alembic marketing ad ./clientes/x brief.json --approve (sem --yes). O que acontece?
Dupla trava: um render pago precisa de --approve E --yes JUNTOS — uma flag sozinha nunca gasta. O comando segue spend-safe e você ainda vê o preview de custo.
10

O mapa dos stores


Tudo que os comandos escrevem cai em stores append-only, em três territórios: o --data-dir da instalação (default .alembic), o store ISOLADO da rota de learnings, e os diretórios "casa" de employees/skills/automations.

<data-dir> (default .alembic) Business/opportunity-graph.jsonl 2.589 signals · +2.677 enriched (676 plausíveis · 399 força-4) memory/<substore>.jsonl — 5 substores: episodic · semantic · procedural · decision · transcript memory add|list · import --write · A3b write-back · --distill --write embeddings-index/<família>.jsonl · vision-index/<família>.jsonl embed-index escreve · search LÊ (cosseno) · vision-index escreve runs/<run-id>/ — events.jsonl · cache · units/ · meta.json run escreve · tui/tail/replay/cockpit LEEM append-only · dedupe por id determinístico ⇒ re-rodar é no-op quem lê nunca é surpreendido por reescrita ~/.alembic-learnings-bkm (store ISOLADO da rota) Skills/learning/learnings.jsonl 1.022 learnings únicos · 100% sourceRefs+hash · confidence μ0.94 escrito pela cadeia --learnings-budget (ADR-0002) · 1ª vez em 06-07 diretórios-casa (defaults dos comandos) ~/.alembic/employees — 43 AI Employees (<id>.json) employee list|show|run leem daqui (--dir troca) ~/.hermes/skills — 148 skills (<name>/SKILL.md) playbooks INTEIROS entram no prompt · import --skills escreve ~/.codex/automations — <id>/automation.toml (PAUSED) employee schedule --out escreve · automation run executa + journal memory.md
Três territórios de escrita. O store da rota de learnings é deliberadamente ISOLADO do data-dir principal — budgets separados, stores separados (ADR-0002).
Você aponta o distill direto na RAIZ da família (…/Resources/Bookmarks). O que acontece?
A família vem do 1º segmento do path RELATIVO ao corpus (family-adapter.ts:98: "top segment = family name"). Na raiz da família o 1º segmento é outro — tudo vira Unknown, residue 0, e NADA avisa. Aponte no PAI de Resources.
11

Gotchas transversais (custaram caro)


O box que você relê antes de qualquer sessão longa
  • Contagens à mão NUNCA: a 1ª execução do scripts/derive-counts.mjs (PR #158) pegou drift vivo — docs diziam 32 comandos; o real era 33/47. Derive da fonte, sempre.
  • Órfãos tinypool: use SEMPRE o baseline com node scripts/safe-test.mjs pnpm -w test — vitest interrompido deixa workers órfãos comendo CPU.
  • pnpm --filter X test pode "passar" sem rodar NADA: pacote sem vitest.config.ts próprio. Confira que testes de fato executaram.
  • Branch nova com dep de workspace ⇒ pnpm install: senão o tsc falha (Cannot find module @alembic/X) enquanto o vitest ainda passa.
  • Squash-merge engana git merge-base --is-ancestor e git cherry: a verdade de "já está em main" é o log de main, não a ancestralidade.
Camada técnica
# o baseline canônico de verificação (CLAUDE.md do repo):
pnpm -r typecheck && pnpm -r build && node scripts/safe-test.mjs pnpm -w test
12

Experimente


Monte a sua primeira sessão de operador inteira em modo $0: doctor --client-stackemployee list → um employee run em dry-run → runs list. Nenhum passo gasta nada, e cada um imprime a verdade que o passo seguinte usa.

Lembra da regra? Se você não passou uma trava explícita, o comando só te CONTOU o que faria — e isso é uma feature, não uma limitação.
Você é o operador agora: escolha UM domínio e rode a receita dele em dry-run hoje. Na próxima página — Operator drills — você decide o comando certo para cada cenário e a página confere. E na Trilha de provas, cada claim deste playbook aparece com o artefato que o prova.