Passo 2 · Avaliação & Prática · Avaliação & Prática · Quiz — Invariantes da casa
Learn Alembic Complete v3 · Visual Course

Quiz — Invariantes da casa

As leis que valem em TODO pacote: Result fail-closed, plano determinístico, append-only + dedupe, dry-run por default, dupla trava de gasto, symlinks que ninguém segue e contagens que ninguém digita. Se você opera o Alembic, isto aqui é reflexo, não consulta.

fusao · 16-the-four-invariants · s0
Você sai daqui sabendo
  • Reconhecer um invariante violado a partir do SINTOMA (verde falso, órfão, drift, módulo sumido).
  • Justificar por que cada default é conservador: preview $0, escrita gateada, gasto com dupla trava.
  • Citar a âncora (arquivo:linha ou comando) de cada invariante sem abrir o repo.
Fonte da verdade

Baseline do spec: pnpm -r typecheck && pnpm -r build && node scripts/safe-test.mjs pnpm -w test — 200 arquivos *.test.ts, 1.834 testes verdes (pré-#159). Âncoras de código citadas em cada explicação.

1

As leis da casa


Invariante não é estilo: é o que continua verdade quando você não está olhando. No Alembic são sete e todas apontam para o mesmo lado — na dúvida, o sistema NÃO age: não lança, não gasta, não escreve, não duplica, não inventa número.

Pense como… a fiação de um prédio: o disjuntor (fail-closed) desarma ANTES do incêndio, e ninguém "confia" que o eletricista lembrou — a régua desarma sozinha. Onde quebra: disjuntor desarmado avisa com escuro; aqui, alguns desarmes terminam com exit 0 — por isso o quiz.

SETE LEIS · UM LEMA: NA DÚVIDA, NÃO AGE o motor: testável · replayável · confiável · barato ① Result fail-closed lib nunca lança; erro é valor tipado ② plano determinístico VM veta Date.now, new Date, Math.random ③ append-only + dedupe id determinístico; re-rodar = no-op ④ dry-run default $0; flag destrava ⑤ dupla trava --approve E --yes; uma flag nunca gasta ⑥ symlink não segue walkCorpus + SkillStore só dir REAL entra ⑦ derive-counts número vem da fonte; mão digita = drift corolários safe-test sempre; verde ≠ rodou
Sete pilares, um teto. Os corolários (safe-test, "verde ≠ rodou") aparecem nas perguntas 8 e 9.
Camada técnica
# o baseline que prova a casa em pé (SEMPRE via safe-test)
pnpm -r typecheck && pnpm -r build && node scripts/safe-test.mjs pnpm -w test
# leia os invariantes na fonte
sed -n '1,40p' packages/contracts/src/result.ts        # Result fail-closed
grep -n "isDirectory" packages/hermes/src/skills/skill-store.ts   # :89 — não segue symlink
grep -rn "dryRun ?? true" packages/marketing-factory/src/ads.ts   # :173 — preview por default
2

As 10 perguntas


Placar cumulativo no fim do bloco. Cada explicação cita a âncora — se discordar de um gabarito, vá à âncora, não à memória.

Prova — Invariantes da casa
Pergunta 1/10 · Result

Qual é o contrato de erro do código de biblioteca no monorepo?

Convenção da casa: "fail-closed Result<T, Error> from @alembic/contracts; avoid throwing in library code". Nos adapters, runWithGuards converte qualquer exceção em failure tipado antes de subir — o chamador nunca vê throw. Âncora: packages/contracts + packages/adapters (spine de guards).
Pergunta 2/10 · determinismo

O que acontece com um alembic.plan.ts que chama Date.now()?

Plano é DETERMINÍSTICO por contrato — replay e cache dependem disso. Prova na fronteira: coloque um Date.now() num plan e rode alembic run --goal GOAL.md --plan alembic.plan.ts --yes; o run falha com erro de não-determinismo (é o item "Non-determinism error" do troubleshooting canônico).
Pergunta 3/10 · append-only + dedupe

Você roda alembic import <sessões> --write duas vezes. O que a segunda rodada escreve?

Append-only + dedupe-by-id é o padrão de TODO store: o id é derivado da fonte (packages/hermes/src/memory/transcript-import.ts:74`${prefix}-${agent}-${session.id}-${index}`), então re-importar não duplica. O mesmo vale para o embed-index (dedupe-by-chunk_id) e para os records de distill.
Pergunta 4/10 · dry-run default

Qual é o comportamento DEFAULT de employee run, import e marketing video?

O default é sempre o caminho que NÃO age: employee run imprime o prompt que SERIA enviado; import lista o que SERIA escrito; marketing video imprime só o custo estimado. --online gateia a chamada, --write gateia a escrita, --approve --yes gateiam o gasto — nunca um default destrava outro.
Pergunta 5/10 · dupla trava

Na marketing factory, o que UMA flag sozinha (--approve OU --yes) compra?

A dupla trava é literal no código: packages/marketing-factory/src/ads.ts:173 (dryRun = opts.dryRun ?? true) e :245 (if (dryRun || !opts.approve) → caminho $0). Uma flag NUNCA gasta — é o mesmo desenho do MCP de marketing (dryRun:false E approve:true).
Pergunta 6/10 · symlinks

Por que uma skill de plugin symlinkada sob a base NÃO entra no import --skills?

Âncora direta: packages/hermes/src/skills/skill-store.ts:89if (!entry.isDirectory) continue;. Um symlink não é diretório para o FsPort, então só <name>/SKILL.md REAIS são importados. O walkCorpus da ingestão tem o mesmo comportamento — symlink nunca é seguido.
Pergunta 7/10 · derive-counts

Os docs dizem 32 comandos; o USAGE exporta 33. Qual é a correção canônica?

Este cenário É a história real: o digest #1 do failure-historian elegeu drift-de-contagem como pior ofensor → nasceu scripts/derive-counts.mjs (PR #158) → a PRIMEIRA execução pegou drift vivo (docs 32; real 33 comandos / 47 formas). Contagem à mão NUNCA — a verdade de hoje é 33/47 porque foi derivada, não digitada.
Pergunta 8/10 · safe-test

Qual é o jeito canônico de rodar a suíte inteira sem deixar órfãos tinypool?

Matar só o vitest main deixa os forks tinypool reparentearem para o PID 1 (~90% de CPU por horas — aconteceu). O safe-test.mjs mata o GRUPO de processos e faz sweep. Por isso o baseline do spec é pnpm -r typecheck && pnpm -r build && node scripts/safe-test.mjs pnpm -w test — decore com o safe-test dentro.
Pergunta 9/10 · verde ≠ rodou

pnpm --filter @alembic/novo test sai verde em milissegundos. O que você confere primeiro?

Gotcha documentado que já enganou gente boa: pacote novo SEM vitest.config.ts próprio (com setupFiles em caminho absoluto) pode "passar" sem executar teste algum — exit 0, zero testes. Confira o CONTADOR de testes na saída, nunca só a cor. A suíte real hoje: 200 arquivos de teste, 1.834 verdes.
Pergunta 10/10 · dep workspace nova

Após checkout de branch que ADICIONA dep workspace, tsc falha com Cannot find module @alembic/X — mas o vitest passa. Qual é o movimento?

O vitest resolve por caminhos que sobrevivem ao checkout; o tsc não — o symlink do workspace só nasce com pnpm install. Depois, pnpm -r build para os dependentes enxergarem os .d.ts novos. CI é imune (instala do zero); sua máquina não. Verde do vitest aqui é o falso amigo.
Acertos: 0/10
3

Para fixar


0
workspaces (27 packages + 1 app)
0
testes verdes em 200 arquivos *.test.ts
0
comandos CLI (47 formas) — derivados
0
ADRs registrando as decisões
fusao · 28-determinism-and-replay · s1
DUPLA TRAVA — ads.ts:173 (dryRun ?? true) · ads.ts:245 (if dryRun || !approve) sem flag só --approve só --yes PREVIEW $0 estimateCost primeiro, sempre --approve E --yes GASTO REAL fail-closed se o job não SUCCEED três entradas caem no preview; só a combinação dupla cruza para o lado pago
Memorize o desenho, não a frase: qualquer caminho com MENOS de duas chaves termina no preview.
Auto-teste relâmpago: se o seu placar ficou abaixo de 8/10, os erros quase sempre estão nos corolários (8 e 9) — os dois casos em que o terminal diz "verde" e a casa diz "prove".
Pergunta para levar: qual invariante desta página protege o funil da página anterior quando o budget estoura no meio de um batch T2? Próxima parada: Quiz — AI Employees, onde a honestidade estrutural entra em cena.