Constituição da Documentação e Engenharia¶
Status: Aprovado · Responsável: Gustavo Madruga · Atualizado em: 2026-10-02
Preâmbulo¶
Esta constituição define o piso da documentação, da engenharia e da plataforma da X-Adm: o que se documenta, para quem, qual o mínimo, e as regras que todo repo da casa segue. Cada regra tem um dono; aqui ficam os princípios e os pisos, uma a três frases por regra, com link para o dono do detalhe.
| Fonte | O que contém |
|---|---|
| Constituição (esta página) | princípios e pisos; nunca mecânica, nunca estado de entrega |
| Normas derivadas (Engenharia, Infraestrutura, Plataforma) | a regra que se executa e se verifica, com âncora estável |
| Decisão (ADR) do central | o porquê de uma escolha, como retrato imutável |
| Skills e templates | o como: ordem, comandos, perguntas; a regra entra por link |
| Toolchain (validadores e guardas) | a cobrança; cada guarda cita a regra que implementa |
| Manifesto | a única lista de artefatos do kit, com perfis e stacks por entrada |
| CHANGELOG do módulo e backlog | a mudança de cada versão e o trabalho em andamento |
Precedência: constituição > ADR do central > norma derivada > template > doc do app. ADR que muda uma regra desta página a altera no mesmo PR; conflito achado é bug do nível inferior.
A norma tem versão própria, separada da versão do kit e da do site: ver Versões.
Princípios¶
Documentação perto do código¶
A doc mora no docs/ do repositório do próprio projeto e muda no mesmo PR que muda o
comportamento. Doc longe do código morre.
Documentar interfaces, decisões e uso¶
O código diz o quê; a doc serve para por quê (decisões), como integrar (contratos) e como usar (quem não escreveu). O que se infere do código não vai para a doc: vira mentira no primeiro refactor.
Docs as code¶
Markdown versionado no Git é a fonte da verdade. Documento gerado (o site, o .docx/PDF de saída)
nunca é editado à mão nem commitado; as exceções são o pré-projeto, que pode ir em .docx, e o badge
de cobertura, que o e2e local grava no repo porque a CI não o reproduz
(CI e testes). Asset de tooling (o
xadm.css, o .docx de referência de estilo, o logo) é insumo do gerador e se versiona como template —
receita em Exportar para .docx.
Decisão é registro; referência é viva¶
Decisão e etapa de projeto são retratos datados: não se reescrevem, superam-se por outro registro.
Manual, runbook e referência têm responsavel: e refletem a realidade — referência desatualizada é
bug. Fato incidental errado num registro se corrige no lugar, com > **Correção AAAA-MM-DD:** …;
premissa errada que sustentava a decisão pede decisão nova. Nota datada só em registro; referência
viva corrige sem nota.
Enxuto por padrão¶
Doc de projeto curto; decisão de cerca de uma página. Seção vazia não existe.
Migração oportunista¶
Doc que não segue o padrão migra quando é tocada; projeto novo nasce no padrão. Adiar trabalho que o padrão recomenda é decisão declarada no fechamento, nunca silêncio (REGRA Nº 3); antes da primeira publicação, renomear custa zero e se faz na hora.
Consulta e compreensão¶
A doc serve quem busca um fato (slug estável, cada ## responde uma pergunta, vocabulário
controlado) e quem quer entender o sistema lendo de cima a baixo — o livro. Folha
endereçável sozinha não ensina o todo.
Português do Brasil¶
Toda a documentação é escrita em português do Brasil.
Duas fontes da verdade: o código e docs/¶
Tudo o mais é transitório ou roteador.
- Andaime (spec, plano, prompt) vive em
.ia/NNN-*.md, fora dedocs/; ao concluir, o durável vai paradocs/. - Segredo nunca entra no Git, nem no andaime.
- Um dono por fato: dentro de
docs/, as outras páginas linkam ou embutem (--8<--), nunca copiam. - Fato de outro repo chega por link ou por importação no build; publicá-lo é obrigação do repo onde ele é verdade — Publicar docs.
Níveis de documentação¶
| Nível | Conteúdo | Audiência | Onde vive | Formato |
|---|---|---|---|---|
| 1. Pré-projeto | estudo de caso e regras de negócio: go / no-go | diretoria | docs/pre-projeto/ |
.docx ou Markdown + Mermaid |
| 2. Projeto | o desenho, antes de programar, e o livro do estado atual | quem implementa e quem mantém | docs/projeto/ |
Markdown + Mermaid + frontmatter |
| 3. Decisões | o que foi decidido, e por quê | quem implementa e quem mantém | docs/decisoes/ |
Markdown + frontmatter |
| 4. Dev | como o código se organiza e como rodar; referência gerada | dev de manutenção | docs/dev/; Javadoc/dartdoc em docs/dev/api/; OpenAPI em docs/public/api/ |
Markdown + frontmatter; referência gerada no CI de docs, opt-in por app |
| 5. Operação | runbooks: deploy, recuperação, operação destrutiva, config de operador | dev e ops da X-Adm | docs/operacao/ |
Markdown + frontmatter |
| 6. Manual | passo a passo com prints | usuário final e suporte | docs/public/manual/ |
Markdown, imagens em docs/public/img/ |
Operação é operar (pressupõe acesso a repo e infra); manual é usar (sem jargão, sem nome de tabela).
- Pré-projeto: problema em uma frase, regras de negócio, clientes impactados, esforço em faixa (S/M/L/XL), riscos, alternativas e recomendação — de 3 a 6 páginas.
- Etapa de projeto: tecnicamente completa para o seu escopo — um dev que nunca viu o código implementa o que a etapa introduz a partir dela e das etapas que ela referencia. O que outra etapa já desenhou se linka; só se reescreve o que esta etapa altera. Molde e seções em Templates.
- Decisão: Contexto · Decisão · Consequências · Alternativas realmente deliberadas. Nasce
rascunhoe viraaprovadona revisão do PR; decisão já em vigor quando registrada nasceaprovado. - Dev: obrigatório em repo com código —
docs/dev/guia-do-codigo.md(como o código se organiza) edocs/dev/como-rodar.md(como rodar), linkados do README. A referência de API é gerada pelo CI de docs, nunca pelo build do app, e é opt-in: o app que não liga a geração não linkadev/api/— link para referência que o pipeline não gera é 404. - Runbook: O que é · Quando usar · Pré-requisitos · Passos · Verificação · Reversão; operação destrutiva abre com aviso. Um dev que nunca operou o app executa só seguindo o documento. As regras de reversão, verificação e contrato externo, e o molde de implantação, estão em Templates.
- Config de operador e diagnóstico de algo que roda sozinho vivem num
operacao/<nome>.mdcurto, linkado da decisão — não num runbook que repete o desenho. - Manual: screenshot é regenerável, com tooling em
scripts/screenshots/e PNG emdocs/public/img/— receita em Screenshots do manual.
Livro, Resumo e nav¶
A Documentação Completa é um esqueleto autorado em docs/projeto/index.md que mostra o sistema
como ele é hoje, numa ordem de raciocínio que termina nos contratos públicos:
- Capa: figura de topologia e fluxos principais, com legenda e, para cada fluxo, como acompanhar se ele rodou ou falhou.
- Contexto e problema, com o que está fora do escopo.
- Dados de entrada e suas regras.
- Modelo de dados — embute
projeto/modelagem.md. - Mapeamento entrada ↔ dados — pode embutir
projeto/mapeamento.md. - Fluxos e processamento, com a arquitetura interna.
- Conceitos transversais e configuração do projeto.
- Contratos públicos e API.
- Apêndice: histórico de etapas e decisões, injetado pelo build.
O livro não reescreve o que tem fonte (modelo, OpenAPI, histórico): embute. O humano escreve o fio
narrativo e o porquê; o agente redige o que consegue ancorar nas fontes e marca o resto para o
humano. Os marcadores e o molde estão em Templates. O deploy não entra no livro: é
procedimento, e mora em operacao/.
Resumo Executivo é a home do app: o problema e como se resolve em um ou dois parágrafos sem
jargão, terminando no livro. O marcador <!-- etapas --> injeta o que já foi entregue e o que está
planejado, a partir do entregue: de cada etapa.
Ordem do nav (obrigatória): Resumo → Mudanças → Pré-projeto → Projeto → Operação → Dev → Público → Etapas → Decisões → Glossário. Desvio que o domínio do app justifique é decisão declarada. Projeto é a especificação (o livro); Etapas é a execução ao longo do tempo.
Repo e frontmatter¶
meu-repo/
├── README.md # o que é o repo, com links para docs/dev/
├── Dockerfile # app deployável como imagem (buildada pelo pipeline.yml)
├── .dockerignore
├── docs/ # privado por padrão
│ ├── app.json # identidade, perfil, versões da norma e do kit
│ ├── index.md # Resumo Executivo
│ ├── pre-projeto/
│ ├── projeto/ # index.md = livro; modelagem.md; etapas NN-titulo.md
│ ├── decisoes/ # NNNN-titulo.md
│ ├── dev/ # guia-do-codigo.md, como-rodar.md; api/ gerado
│ ├── operacao/
│ ├── public/ # público: index, manual/, img/, api/
│ └── anexos/ # apoio interno, com README; privado/ fica fora do build
├── scripts/ # tooling de dev e ops; scripts/sql/ para SQL que não é dado
└── .github/workflows/pipeline.yml
App deployável leva Dockerfile e .dockerignore desde o primeiro commit de código, derivados dos
templates, junto do .gitattributes da stack — é neles que vive o health check obrigatório. Repo que
não deploya imagem (lib, CLI distribuído como artefato) não os tem.
Perfis de repo¶
Todo repo no loop desta constituição tem docs/app.json com o campo perfil:
app(padrão, quando o campo falta): server Micronaut, Flutter web, CLI on-prem, serviço auxiliar. Carrega o kit completo.config: stack de serviço self-hosted (as stacks PowerSync) —app.jsonmínimo, regras de IA, hook, skills,VERSION+CHANGELOGe opipeline-config.yml. Não publica site.lib: oxadm-commons—app.jsonmínimo comtoolchain, hook, skills e checkstyle; o pipeline, a/xadm-releasee o índice de CHANGELOGs são customização local declarada (Bibliotecas da casa).
O que cada perfil e stack recebe está no manifesto
(regras de bump e uso em Versionamento), não em prosa:
a /xadm-docs filtra pelo dado. Cada página de engenharia abre com "Aplica-se a: …".
Frontmatter¶
Todo .md publicado leva frontmatter, exceto os fragmentos embutidos por --8<-- e as páginas-índice
que o validador lista. Esta seção é a dona dos campos:
---
titulo: "..."
tipo: projeto | decisao | dev | operacao | manual | livro
status: rascunho | em-revisao | aprovado | obsoleto
responsavel: "Nome <email>"
modulo: combustiveis | transporte | fiscal | financeiro | estoque | compras | vendas | integracao | comum
cliente: "..." # só em app de cliente
atualizado: AAAA-MM-DD
decidido_em: AAAA-MM-DD # decisão aprovada: quando foi tomada
entregue: true | false # etapa: a feature foi entregue (independe do status do doc)
entrega: "..." # etapa: frase de negócio para o Resumo Executivo
superado-por: "NNNN" # decisão obsoleta
supersede: "NNNN" # decisão que substitui outra
tags: [...]
---
responsavel:é obrigatório e responde pelo conteúdo; doc sem ele não chega aaprovado.decidido_em:é obrigatório em decisãoaprovado;entregue:é obrigatório em toda etapa (diversos.mde o livro são isentos).- Id de decisão vai entre aspas: sem elas o YAML lê o zero à esquerda como octal.
tipo: livroé oprojeto/index.md, semmodulo:;moduloé enum fechado (módulo novo = PR no central) e app de cliente sem módulo de negócio usaintegracao.
Convenções de doc¶
- Abrangência: app da X-Adm (produto, todos os clientes do módulo usam) ou app de cliente (sob
medida, com
cliente:no frontmatter). - Nomes de arquivo: etapa
projeto/NN-titulo-curto.md(duas casas, sem ano); etapa avulsa emprojeto/diversos.md; decisãoNNNN-titulo-curto.md, sequencial por repo. - Slug estável: o nome do arquivo é o ID público da página; renomear exige redirect.
- Caminho × papel: caminho concreto, em code span, só quando é interface (endpoint, tabela
compartilhada, env, caminho-contrato); mecânica interna se descreve pelo papel. URL do Forgejo só em
página de
privado/, e link relativo para fora dedocs/é proibido. - Público e privado:
docs/é privado por padrão; o público de cada app é o que está emdocs/public/, e página pública não linka para fora dela.privado/é sempre excluído do build e é onde fica dado real de cliente. - Massa de dados: planilha, dump e banco são proibidos em
docs/fora deprivado/(o.docxde pré-projeto é a exceção). SQL que não é dado vive emscripts/sql/; a página que precisa mostrá-lo transclui, sem literal de cliente. Detalhe em Publicar docs. - Modelo de dados: projeto com banco ou contrato de dados mantém
projeto/modelagem.md, o modelo consolidado do estado atual, e toda etapa que evolui o modelo o atualiza no mesmo PR. - Fragmento embutido (
modelagem.md,mapeamento.md, arquivo-fato) não tem frontmatter e se escreve no nível do embed: os títulos começam em###. - Diagramas: Mermaid inline, fluxograma em
TB; o CI de docs linta cada bloco. Figura de capa pode ser SVG autoral com o Mermaid-base junto. Receita em Templates. - Glossário: cada repo define em
docs/glossario.mdo vocabulário do seu domínio e linka termo de outro glossário por URL absoluta.
Engenharia¶
Como construir mora na área de Engenharia: gate de CI e níveis de teste em CI, gates e testes, versão em runtime e health check em Versionamento, receita por stack nas páginas de cada stack. Aqui ficam os princípios.
- Libs da casa na corrente. App elegível declara a última versão publicada de cada módulo do
xadm-commonsque consome (fonte:maven-metadata.xmldo registro); atrás da corrente é pendência; abaixo do piso a/xadm-releaserecusa. Adotar uma versão é migrar no mesmo PR, pelas seções### Migraçãodo CHANGELOG do módulo — Bibliotecas da casa. - Server Micronaut: native por padrão; jar declarado com motivo. O motivo é bloqueio de native
registrado em ADR do app, ou host de runtime sem a arquitetura do binário. O app é native se e só se
build.targetscontémnative— 0033. - Reflexão sob AOT se auto-gera. Recurso alcançado só por reflexão (views JTE, appender) tem o registro gerado pelo build, nunca listado à mão: lista à mão esquece o item novo e o native serve 404.
- Comentário de linha ou de bloco é uma linha, só para o porquê que o código não mostra; Javadoc e dartdoc de API seguem o padrão da linguagem e documentam o contrato. A história vai para o commit, o CHANGELOG ou a decisão; armadilha de linguagem ou framework vai para as Armadilhas da página da stack — Stack da casa.
- UI server-render usa o layout padrão X-Adm (o kit de UI do manifesto, na paleta do
xadm.css), inclusive tela de admin. Ocustom-theme.cssé identidade da casa e não se edita por app; oapp.cssé dos componentes do app — Java/Micronaut.
Plataforma¶
Central de Apps¶
O central-backend (central-backend.xadm.biz) é o backend da Central de Apps e da autenticação; o
central-ui (central.xadm.biz) é o dashboard. Detalhe em Central de Apps.
- Setup em build-time. O app declara no
app.jsono que usa; a/xadm-setupprovisiona pelocentral-backende grava de volta o resultado client-grade, que o build embarca. Nada de buscar config no boot. - Broker de setup é M2M, autenticado por token de serviço cuja força casa com a exposição do endpoint. A regra de geração do token vive fora de banda, nunca na skill nem em doc publicada.
- Uma identidade por app: o
app_id(kebab, no mesmo namespace dos grants) é o mesmo valor dosluge do projeto de erro; o validador barra a divergência e renomear é migração em duas fases — 0038. - Papel: o app declara, o central concede. O app publica o catálogo de papéis
(
roles-catalog.json) e ocentral-backendo ingere; o grant é por(cliente, app, subject, role)— 0029. - Auth social usa um projeto de identidade só: o token identifica o projeto, não o app, e a autorização por app vem sempre do grant — 0030.
- Observabilidade é baseline: todo app com release tem rastreamento de erros no GlitchTip.
- Fronteira de dados: autenticação e autorização no banco do
central-backend; domínio e estado de flags no banco do app.cliente_id(chave) ≠cliente(rótulo); a plataforma escopa pela chave declarada e nunca a deriva do rótulo. - Segredo nunca vai em
docs/, noapp.json(público) nem no bundle.
Plataforma de Integração¶
Detalhe, taxonomia e transporte em Plataforma de Integração.
- O ponto de integração é o banco por cliente. A Plataforma de Integração é a cópia fiel do X-Adm nesse banco; o que vem de fora entra por apps específicos, donos das próprias tabelas.
- Organiza-se por tipo de fluxo de dados, não por cliente: o genérico é único e estável; o que diverge se isola por peça, com deploy independente.
- Owner-writes: cada tabela do banco tem um dono, que roda o Flyway e escreve; os demais leem. A tabela-espelho modela a entidade do X-Adm, e campo de origem externa entra prefixado, só como rastreabilidade.
- Transporte padronizado por direção, entrega garantida por fronteira: PowerSync entre o banco e os clientes, REST entre a Plataforma e os apps específicos, e cada travessia com o seu mecanismo de entrega — Entrega garantida.
- O fio inteiro se prova local: fluxo de integração tem suíte e2e-local, com os apps de verdade e fake só nas bordas.
Entrega¶
Detalhe em Deploy, Operação no Coolify e Smoke de produção.
- Build fora do host de produção. A imagem é buildada pelo
pipeline.yml, num runner fora do host que serve produção; o Coolify só puxa. Recurso deployável declara limite e reserva de memória. - Config de build-time vive onde o CI alcança:
ARGcom default no git,docs/app.jsonou secret do repo; env de runtime fica no recurso. Endereço que oapp.jsonjá declara é derivado dele no build, nunca copiado à mão. - A tag
vX.Y.Zé o release: opipeline.ymlbuilda os alvos do trailerDeploy:(fallbackbuild.targets) e chama o control-plane. Push emmastersem tag só publica odev/da doc. - O deploy é disparado pelo control-plane: o CI faz
POST /api/ci/deploynocentral-backend, com token de serviço, e o central dispara o recurso no Coolify. Auto-deploy do Coolify fica desligado; os recursos que o Coolify builda do git estão listados em Deploy. - Deploy só com gate verde e release válida. O pipeline não tem caminho que deploye com o gate pulado ou vermelho; emergência é consertar o teste, ou reverter à mão no Coolify apontando a tag imutável.
- O mapa app → recurso casa pelo slug do artefato que o recurso consome (a imagem; no compose, o repo git), nunca por uuid nem por nome — 0026.
- Deploy só encerra com smoke verde. Todo app deployável declara
smoke.routesnoapp.json: o/healthe uma rota de cada classe de credencial que ele serve. Depois do deploy o CI confere a identidade do que está no ar, as rotas declaradas e a ausência de exceção nova no GlitchTip. - A tag imutável
<imagem>:<sha>-<target>é a saída de emergência: o registry retém as dez últimas por imagem e alvo, e nunca poda a que está no ar. - URL que outro sistema consome aponta o domínio estável do serviço, nunca o de um flavor de build ou de uma instância.
- Repo de config usa o
pipeline-config.yml: gate de config e deploy pelo control-plane comtarget=compose.
Governança¶
- Por documento: o
responsavel:responde pelo conteúdo, e o hook do MkDocs mostra status, responsável e data no topo de cada página. - No PR: mudou contrato, schema ou fluxo público, a doc correspondente muda no mesmo PR; revisão de doc é parte do code review.
Definição de pronto¶
Mudou código, o mesmo PR traz:
- Teste proporcional ao risco, exercitando a plataforma e o runtime reais; em componente compartilhado o risco se multiplica pelos adotantes — regras em CI, gates e testes.
- Doc do estado atual: README, runbook, contrato, livro e screenshot que mentiriam depois da mudança são corrigidos no mesmo PR.
- Compatibilidade com o rollback: DDL destrutivo segue expand/contract — a release N não remove o
que a N-1 usa —, com o marcador
-- destrutivo-ok:no.sql.
Pular qualquer item é decisão declarada no fechamento, nunca silêncio.
Todo repo tem CI que cobra o piso: a doc (Publicar docs), o
código (job gate do pipeline.yml, com o contrato de release na tag — CI, gates e testes)
e a config (pipeline-config.yml — PowerSync).
O do central cobra também a redação da norma, o manifesto e os testes de cada gate.
Versões¶
- Três números, três coisas: a norma (o
versao:desta página) sobe quando a norma muda — esta página ou qualquer norma derivada, porque é por esse número que a frota detecta a mudança; o kit (arquivoKIT) sobe quando template, script ou skill muda; o site (VERSION) é a release do portal. Regra mais restritiva sem bump da norma é regra que ninguém vê chegar. - Versão-base: o
docs/app.jsonde cada repo registraconstituicao(a norma que segue) ekit(o kit que sincronizou). É o único lugar do número; oCLAUDE.mdaponta para o campo. - Kit defasado se re-deriva; norma defasada se re-audita, com aprovação do usuário. Manifesto, regras de bump, aviso de defasagem e validador fresco em Versionamento.
Regras de redação¶
- Uma regra, um lugar; os outros linkam com âncora.
- Presente, sem histórico: a norma não cita episódio, data, número de spec ou de item de backlog, nem versão de release; o porquê vai para a ADR, a mudança para o CHANGELOG.
- Supersede, não empilha: mudou a norma, o parágrafo se reescreve no mesmo PR.
- Até três frases por item desta página (regra, porquê, link); mais que isso é receita e vai para a norma derivada. O orçamento desta página é de 500 linhas.
- Exceção nominal (um app, um recurso em dívida) não mora aqui: fica na norma derivada, com dono.
- Vocabulário: obrigatório, proibido, opcional. "Padrão" só existe com o mecanismo de exceção definido.
- Seção se cita pelo nome, com link para a âncora, nunca por número.
- ADR aprovada só recebe correção de fato incidental, visível; decisão nova é ADR nova com
supersede:.
O checa-redacao.py cobra estas regras no núcleo, nas normas derivadas, nas páginas satélite
(documentação, transversais, glossário e início) e nos templates do kit.
Regras de IA¶
Todo repo abre o CLAUDE.md com o bloco canônico de templates/claude-regras.md:
- REGRA Nº 1 — não decidir sozinho: ambiguidade ou mais de um caminho → opções com uma recomendação e confirmação antes de implementar.
- REGRA Nº 2 — não commitar nem pushar sozinho: a exceção é a
/xadm-release; fora dela o agente entrega a mensagem de commit pronta, sem atribuição de IA. - REGRA Nº 3 — deferir é explícito: adiar o que o padrão recomenda se declara no fechamento.
O CLAUDE.md (roteador, com teto de linhas), o .claude/settings.json e o fluxo de trabalho com IA
(/x-desenhar → … → /x-documentar) estão em IA e Claude Code e
Ferramentas.
Feedback¶
Quem aplica o padrão e encontra lacuna, ambiguidade ou conflito não contorna localmente: escreve o problema para ser tratado numa sessão do repo central. O texto diz de onde vem (repo, versões da norma e do kit), o que se fazia, o que foi medido e o que é suposição, e aponta a fonte em vez de parafrasear.
Todo fechamento de trabalho traz, junto da mensagem de commit, a linha de feedback, afirmativa:
Feedback: nada a reportar ou Feedback: candidato — <o quê>. Sem ela, o passo foi pulado.
No central, o feedback passa por revisão adversarial contra a norma vigente: entra o que corrige,
generaliza ou substitui uma regra, reescrita no lugar, e cada aceite mostra o que saiu ou foi fundido;
mudança que só acrescenta leva a justificativa escrita no backlog. O que só acrescenta o caso de um repo é
remendo e é recusado. Cada ponto volta ao repo como Resposta do central: aceito | já coberto | recusado |
pendência — <onde ou por quê>.