ADR-0082 — Escopos e partições: isolamento de falha dentro do monorepo
20/09/2026 · aceito
docs/adr/ADR-0082-escopos-e-particoes.md
ADR-0082 — Escopos e partições: isolamento de falha dentro do monorepo
Status: aceito
Data: 2026-09-20
Decisor: fundador (brainstorm da extensão 15, 19/09)
Gates: tests/standards/escopos.test.ts (cobertura e existência), scripts/ci/escopos.test.ts (loader e gramática), tests/standards/early-exit.test.ts e tests/standards/mergify-gerado.test.ts (consumidores — Tasks 6 e 8), mergify config validate (schema vivo da Mergify) — rodado no PR; virar check é card
Decisão
O monorepo é dividido em 4 escopos — plataforma (catch-all), jep, infra, docs — declarados em config/escopos.yml. O contrato tem duas noções distintas: dono de um job pesado (escopo: runner e partição) e relevância (relevancia: os paths cujo diff torna o resultado do job obsoleto). Três consumidores leem o contrato: early-exit dos jobs pesados (decide POR JOB, pela relevância — nunca pelo dono), escopos da fila Mergify (pelos paths dos escopos) e label de runner (Plano 2). Repo separado por unidade não é adotado agora.
- Fila em in-place checks (
max_parallel_checks: 1,batch_size: 1,merge_conditions == queue_conditions): a Mergify recusou o 1º enfileiramento porquestricté incompatível com PRs de lote. Mantemosstrict(lição do legado) — serial com isolamento de falha;scopesdeclarados para o dia em que houver volume. Descoberto que a fila nunca operou antes (labelqueueinexistente; 21 merges diretos).
Por quê
- O objetivo é isolamento de falha (decisão do fundador), não capacidade nem repo próprio.
- Os cruzamentos vividos (host, portas,
/tmp,smokevermelho em todo PR) vêm de recurso compartilhado, não da estrutura de repos; 71% da fricção medida é CI/ambiente (liçãod5907231) — polyrepo multiplica isso. - Mergify
scopesagrupa a fila por área quandomerge_queue.modeéparallel/isolated(PRs do mesmo escopo testados em lote, áreas distintas em paralelo). Hoje o modo éserialin-place (ver bullet abaixo);scopesfica declarado e inerte até o dia em que ligarparallel.partition_rulesfoi removido da Mergify em 2025-10-31. - Dono ≠ relevância porque 2 dos 3 jobs pesados têm predicado mais fino ou mais amplo que o escopo dono:
promptfoopertence aojep, mas seu golden set vive empromptfoo/**(plataforma) — decidir pelo dono pularia o gate de eval no PR que edita o próprio golden set. mobile-compilefica fora do contrato (runner macOS pago; mantém o early-exit interno).
Não-negociáveis
- Nunca
paths:no gatilho do workflow (liçãoa7a403ba, G12): o job sempre roda e é sempre required; só o 1º step decide, fail-closed. - Diff com
--no-renames: mover um arquivo para fora de um escopo conta como tocar o escopo. - Gramática de glob só
**e*; qualquer outro metacaractere,./inicial ou/final é recusado no carregamento — typo vira vermelho, não escopo furado.
Critério de permanência / reversão
4 semanas após X3 (extensão 15 §10): colisões por partição, duração de PR só-plataforma, falso-positivo dos gates novos. Vazamento de credencial entre escopos ⇒ Abordagem B (infra em repo próprio). Reverter = apagar o contrato e os consumidores; os workflows voltam a rodar tudo.
-
Se o volume justificar paralelismo, a troca é
strictOFF +max_parallel_checks> 1 — decisão de board (afrouxa proteção). -
Custo do promptfoo: hoje o provider é
echo(eval grátis); quando virar modelo real, revisarroda_tudo_se_tocar× custo — todo PR emscripts/ci/**ou lockfile roda a eval completa.
Só leitura. Toda mudança nestes documentos é pull request.