Arquitetura
O DOP são três repositórios que entregam e um que os fixa. Os componentes são repositórios git independentes, agregados como submódulos pelo repositório guarda-chuva, que carrega a documentação do produto: o PRD, as ADRs, as specs e as coleções da API.
Os componentes
- dop-coreGoO core: domínio, estado, transações e o log de eventos.Um binário, quatro modos (serve, worker, sched, launcher). É dono do schema e do vault; é a única fonte da verdade, e verifica a assinatura de todo chamador.dop-core ↗
- dop-apiPythonO BFF: REST e SSE para o cockpit, gRPC para a CLI.Não tem banco nem segredo. Traduz e encaminha; toda escrita passa pelo core.dop-api ↗
- dop-appReact · ViteO cockpit onde o desenvolvedor trabalha.A caixa de atenção, a árvore de workspaces e projetos, o cockpit da demanda. Consome um contrato commitado e gera dele os seus hooks e schemas.dop-app ↗
- dop-infraTerraform · k3dA infraestrutura da plataforma.Terraform para o Google Cloud (Cloud Run, Secret Manager, Identity Platform) e um ambiente local em k3d com Postgres, NATS JetStream e os emuladores do Firebase.dop-infra ↗
- sandboxmicroVMUma por demanda, com um único worktree compartilhado.A fronteira dura é entre contas e entre demandas. O conhecimento do projeto é clonado lá dentro como um repositório git; a verificação roda da fonte num runner efêmero.
Os diagramas
Seis figuras, da plataforma inteira até cada componente. Todo nome nelas é um pacote, um port ou um adaptador que existe nos repositórios; o que está planejado e não construído aparece tracejado.
A plataforma
O core por dentro — o hexágono
O BFF por dentro — dois transportes, uma regra
Eventos e o motor de fluxos
O motor de fluxos
O caminho da falha
O cockpit por dentro
Como o core verifica seus chamadores
A plataforma e com quem ela conversa
As cinco invariantes
As paredes estruturais da arquitetura. Uma mudança que quebra uma delas está errada mesmo quando compila e os testes passam.
- O core é a única fonte da verdade.É dono do schema e do vault. Toda escrita passa por ele.
- O BFF não tem banco nem segredo.Traduz e encaminha; nunca persiste e nunca guarda uma credencial.
- Os arquivos .proto são o contrato.Código gerado é regenerado, nunca editado à mão. Uma mudança incompatível é recusada de propósito.
- O cockpit consome um contrato commitado.A spec OpenAPI é baixada e commitada; os hooks do react-query e os schemas Zod são gerados dela.
- O core verifica seus chamadores, e a verificação roda da fonte.Uma assinatura em toda chamada, nunca um header de confiança. Uma verificação constrói do repositório num runner, não de uma imagem.
A vida de um evento
Toda escrita no core emite um evento na mesma transação. O que acontece depois é infraestrutura, não problema do repositório.
- escritaUma transação no Postgres muda o estado e anexa o evento à outbox — um commit, ou nenhum.
- outboxUm relay lê a outbox e publica no NATS JetStream. O id da mensagem é o id do evento, então uma retentativa não duplica.
- envelopeO evento viaja com o seu contexto: chave do agregado, ator, id da requisição, id da sessão, chamador.
- consumidorUm consumidor o processa. Em falha, é reentregue com backoff, até cinco vezes.
- dead letterEsgotado, o evento vai para uma única fila de dead letters com o histórico de tentativas e a sua classificação: recuperável, irrecuperável, desconhecida.
- ledger de errosToda falha é registrada por (evento, consumidor); uma assinatura que queima todas as retentativas duas vezes é aprendida como irrecuperável, e um sucesso a rebaixa.
O registro de decisões
Toda decisão estruturante, no formato MADR: contexto, decisão, alternativas consideradas, consequências. Um assunto, uma ADR.
- 0001 Infraestrutura atrás de ports, com adaptadores plugáveis
- 0002 Tenancy: a conta é dona de tudo, e uma organização se prova pelo domínio
- 0003 Uma credencial da organização para agir, autoria humana no commit
- 0004 A demanda é um log de eventos; todo o resto é projeção
- 0005 Sem verde, sem PR: verificação nativa e uma fila de merge por repositório
- 0006 Contexto é um subsistema: uma base de conhecimento e um pacote por demanda
- 0007 Multiagente por demanda: threads endereçáveis e achados publicados
- 0008 O custo do LLM: medir, limitar, rotear e gastar menos
- 0009 O recurso como unidade de posse e compartilhamento da conta
- 0010 Um fluxo dinâmico, tipado e herdável
- 0011 O orquestrador do projeto: o agente techlead
- 0012 Um core em Go, um BFF em Python, e a fronteira entre eles
- 0013 O .proto é a fonte da verdade do contrato
- 0014 PostgreSQL como banco único, e a outbox que move seus eventos
- 0015 Emuladores do Firebase no ambiente local; Terraform como dono único
- 0016 O runtime do agente: um port por fornecedor, rodando dentro do core
- 0017 Uma microVM por demanda, com um único worktree compartilhado
- 0018 Comunicação: o gatilho e o canal nascem juntos
- 0019 O convite não tem segredo: identidade no lugar de um bearer
- 0020 O segundo fator é da plataforma, com três verificadores
- 0021 O conhecimento do projeto é um repositório git, hospedado pela plataforma
- 0022 O core verifica uma assinatura; não acredita num header
- 0023 A verificação constrói da fonte num runner, não de uma imagem