Checklist: app novo entrando no padrão¶
Passo a passo para colocar a documentação de um app novo no ar. Em ~30 min o
site do app aparece em docs.xadm.biz/aplicacoes/<app>/.
1. Escolha o slug — com calma¶
O slug (nome do repo e do prefixo no bucket) é o ID público do app, para sempre: vira URL, links e alvo do futuro RAG. Renomear depois quebra tudo.
- minúsculas, hífens, sem acento:
bi-transporte-xls, nãoBI_TransporteXLS - confira a grafia em voz alta antes de criar o repo: um typo aqui fica permanente
2. Crie o repo no Forgejo¶
- Em
fonte.xadm.biz, na organização certa. - O repo e a pasta do clone nascem com o slug. A 0038
não obriga a renomear pasta de repo antigo — o caminho na raiz multi-repo é legibilidade humana e o
app.jsoné quem liga pasta e identidade —, mas repo novo não tem esse custo: nascer com o nome certo evita a divergência de saída. Na raiz multi-repo, o.code-workspacerotula cada pasta pelo slug, então o histórico continua legível sem renomear nada. - Estrutura
docs/de Repo e frontmatter:index.md(Resumo Executivo),glossario.mde, conforme o caso,projeto/(Etapas),decisoes/,dev/,operacao/, epublic/(manual + API públicos) (criepublic/img/junto com a primeira screenshot — Git não versiona pasta vazia). Repo com código temdev/guia-do-codigo.mdedev/como-rodar.mdobrigatórios (Níveis de documentação); o validador os cobra em app combuild.targets. - Crie
docs/anexos/edocs/anexos/privado/com os READMEs canônicos (templates/anexos-readme.mdetemplates/anexos-privado-readme.mddo repo central): anexo público emanexos/, dado real de cliente só emanexos/privado/— nunca publicado (Convenções de doc). - Use os templates de documento — frontmatter no formato da seção Frontmatter da constituição.
- App de cliente? O frontmatter leva
cliente:(ver Convenções de doc). - Crie
docs/app.jsoncom os metadados do app — é ele que faz o app aparecer com nome e grupo certos na página Aplicações. Operfilausente valeapp(Perfis de repo); okitquem grava é a/xadm-docs. App Java/Flutter: declaretoolchain(ex.{ "java": "25" }) — é obrigatório (o validador falha sem ele). A versão alimentasetup-java/subosito/flutter-actionnopipeline.yml(decisão 0027) — a validade da versão é atestada pela própria action no run. Casar.fvmrc=toolchain.flutter. - Central de Apps: declare o
app_id(identidade canônica). As funcionalidades (erros, arquivos, analytics, docs) você configura depois de codar e antes da release, rodando/xadm-setup— ele pergunta o que ativar, provisiona e preenche o blocofeaturesdoapp.json(build-time). Ver Central de apps. - Crie
docs/changelog.mda partir detemplates/changelog.md— uma linha que embute oCHANGELOG.mdda raiz (--8<-- "CHANGELOG.md"); omkdocs.ymljá vem com a entrada de nav "Mudanças". Fonte única: não copie o conteúdo, só o stub. - Crie
overrides/main.htmla partir detemplates/overrides-main.html(omkdocs.ymljá apontatheme.custom_dir: overrides) — é o aviso de "versão antiga" do seletor de versão (decisão 0004). Ocustom_direxige o arquivo existir, mesmo antes de versionar. - Garanta
site/no.gitignore: o build local do MkDocs (passo 5) gera a pasta na raiz do repo, e site gerado nunca é commitado (Docs as code).
3. Copie os templates canônicos do repo central¶
Antes de copiar, confira as versões vigentes da norma e do kit em
constituicao-versao.txt e
kit-versao.txt — e re-confira ao terminar a adoção: se mudaram no meio, re-derive os
templates copiados; o app.json registra as versões que os templates realmente seguem.
Três números, não confundir (Três versões):
- a norma —
constituicao-versao.txt=app.jsonconstituicao; - o kit (templates, scripts, skills) —
kit-versao.txt=app.jsonkit; - o site —
VERSION,/versao.txte a tagvX.Y.Zdo repo central: a release do portal.
O app registra os dois primeiros. O número do site nunca é versão-base — num clone local do central, é o engano mais fácil.
Baixe sempre do mirror público docs.xadm.biz/toolchain/ — nunca de um
clone local (diverge) nem do fonte.xadm.biz (o Forgejo é privado: serve
edição/hosting e dá 404 sem auth — inviável num bootstrap, inclusive por
agente de IA). A lista canônica e a versão de cada artefato vivem no
manifesto.json (a mesma
fonte única que a /xadm-docs consulta); o conteúdo cru de cada um está em
https://docs.xadm.biz/toolchain/raw/<caminho> — ex.:
curl -fsSLO https://docs.xadm.biz/toolchain/raw/templates/mkdocs.yml
Copie cada artefato para o destino abaixo (o nome do template ≠ caminho no app
em alguns casos — o mesmo mapa que a /xadm-docs aplica):
templates/mkdocs.yml→mkdocs.ymlna raiz do app (troque<app>)templates/pipeline.yml→.github/workflows/pipeline.yml(troque<slug>, mantenha só a variante da sua stack — CI/CD único, decisão 0027; o branch émaster, já no template)xadm.css→docs/stylesheets/xadm.css(identidade visual)templates/claude-regras.md→ bloco no topo doCLAUDE.mddo repo (Regras de IA: não decide sozinha, não commita sozinha).templates/settings.json→.claude/settings.json(allow-list base do agente — universais em Bash+PowerShell). Some as linhas da sua stack (Java:./gradlew/jar/javap/unzip; Flutter:flutter/dart; Node:npm) e o hookSessionStartdocheca-constituicao.sh(abaixo). Path de máquina fica FORA: se o JDK default da máquina ≠ a toolchain do app, ponhaenv.JAVA_HOMEno.claude/settings.local.jsongitignored — senão o agente prefixaJAVA_HOME=… ./gradlewe quebra o allowBash(./gradlew *)a cada build. Regra: Ferramentas § higiene do settings.json.- Skills (
.claude/skills/<nome>/SKILL.md) — instale TODAS, não só duas. Copie todas as*-skill.mdque omanifesto.jsonlista, exceto as do campoopcionais(hoje sóxadm-docx— export Word para a diretoria; instale apenas se o app gera.docx). O conjunto core que todo app conformante carrega são 10: as 6 de workflowx-desenhar,x-definir,x-refinar,x-planejar,x-implementar,x-documentar+xadm-meta-audit-work,xadm-docs,xadm-releaseexadm-setup(Central de Apps — o passo 2 manda rodá-la depois de codar, antes da release). Asx-*são diretórios (templates/<nome>/com SKILL.md +references/) → copie o diretório inteiro para.claude/skills/<nome>/; asxadm-*são arquivo único (templates/<nome>-skill.md→.claude/skills/<nome>/SKILL.md). Não pare em docs+release: omanifesto.jsoné a lista mecânica completa — cruze com ele, não com esta prosa. Duas skills têm passo extra:xadm-docs— copie tambémtemplates/checa-constituicao.sh→.claude/checa-constituicao.she crave o hookSessionStartno.claude/settings.json(obrigatório — otemplates/settings.jsontraz só env+permissions, então sem cravar o hook o.shfica presente porém nunca acionado; o bloco está no topo do script). Preenchaconstituicaoekitnodocs/app.jsoncom as versões vigentes (Versões); oCLAUDE.mdaponta para o campo, sem repetir o número.xadm-release— troque<app>/<repo>e mantenha só o bloco de "Particularidades" da sua stack. É o wiring de release, fácil de esquecer porque a doc flui antes: instale junto, não depois. OCHANGELOG.mdnão se cria à mão — nasce na primeira/xadm-release(infere dogit loge cobre o histórico). Ver versionamento.
App que renderiza HTML no servidor (Micronaut Views/JTE — telas de admin/ops/dev,
inclusive internas e atrás do gate de auth) copia também o kit de UI opcional
(templates/views-jte/kit/** → layout.jte, headerRight.jte e pager.jte, mais templates/public/**
→ custom-theme.css, logo.png, favicon.ico) e usa o layout padrão X-Adm em vez de
reinventar o visual (Engenharia, decisão 0025). Copie também o scaffold
templates/app.css → public/css/app.css (CSS de componentes deste app; o kit sempre o
linka — sem o arquivo, 404 em toda página). Ausente no opcionais do manifesto para app
headless/Flutter. Receita e
static-resources em Java/Micronaut §UI.
Hook de estilo terso (recomendado): some ao .claude/settings.json o hook SessionStart
que injeta a regra de output terso + o carve-out verbatim da casa (.claude/caveman.sh) — corta
~65–75% dos tokens de output do agente, exatidão intacta, e protege os deliverables (mensagem de
commit, linha de feedback, .ia/) da compressão. Receita em
Ferramentas § caveman.
Não copie de outro app — clones divergem do padrão.
Template × piloto — não confundir a fonte
O template (vem do central, sincronizado via manifesto) é a única fonte de cópia para um app novo. Um app piloto / de referência (por stack, citado nas páginas de Engenharia) é o exemplo onde o padrão foi provado e destilado — serve de referência, nunca de base de cópia (copiar dele = "clones divergem"). O que um app novo segue vem de: templates + a página de Engenharia da stack + a skill da stack, não de clonar um piloto.
4. Secrets — nada a criar, só confira¶
Os secrets DOCS_S3_ENDPOINT, DOCS_S3_ACCESS_KEY e DOCS_S3_SECRET_KEY
são secrets deste repo no GitHub (a conta é user-wide, não org — decisão 0027; a key
de escrita no bucket docs-sites é a mesma para todos os apps, cadastrada em cada repo — ver
Garage). O aviso de
falha do CI é a notificação nativa do GitHub (email ao autor) — nada no YAML, sem secret
(Forgejo e CI ·
0027).
Credenciais — não confundir (Central de Apps é build-time)
O client-grade (DSN, app key, bucket) não é secret — vive no app.json (o
/xadm-setup grava). São secrets (fora do app.json): (1) DOCS_S3_* — publicação de
docs, secret por repo no GitHub (conta user-wide, não org); (2) key de escrita do Garage (só web/server, se usa arquivos) — o
/xadm-setup registra e o deploy injeta no Coolify (mobile escreve via presign); (3)
SENTRY_AUTH_TOKEN (upload de sourcemap do GlitchTip), idem. Ver
Central de apps.
5. Valide e publique¶
- Local (opcional):
mkdocs build --stricte o validador de frontmatter — no Ubuntu, instale o MkDocs via pipx (como configurar); o validador, baixe do site (não copie para o repo do app):curl -fsSLO https://docs.xadm.biz/toolchain/valida-frontmatter.py && python3 valida-frontmatter.py docs/. - Push no branch padrão → o workflow builda, valida e publica no bucket →
em ~2 min o site está em
docs.xadm.biz/aplicacoes/<app>/. - A entrada na página Aplicações (e na API
Reference, se houver
api/) é automática — confira se o app apareceu no grupo certo; se caiu em "Outros", oapp.jsonnão foi publicado ou está inválido. - Resumo Executivo (Livro, Resumo e nav): a home (
index.md) é a porta do diretor — problema + como resolve, sem jargão, 1–2 parágrafos, terminando em "→ Documentação Completa". Ponha<!-- etapas -->e o hook injeta as listas "entregue/planejado" do campoentrega:+entregue:(obrigatório) de cada etapa. Template: Resumo Executivo. - Documentação Completa = o livro do sistema, autorado (Livro, Resumo e nav): crie
docs/projeto/index.mda partir do template — um esqueleto na ordem lógica (contexto → dados → modelo → mapeamento → fluxos → transversais → contratos → changelog) que mostra o sistema no estado atual, não a soma das etapas. Você escreve o fio narrativo; o factual vem das fontes: o<!-- GERADO: changelog -->injeta etapas+decisões, e um<!-- RECONCILIAR: … -->falha o build até reconciliar. Projeto com banco: crie tambémprojeto/modelagem.md— o modelo de dados consolidado (ER Mermaid), embutido no livro e atualizado por toda etapa que evolui o banco, no mesmo PR (Convenções de doc). - Etapas do Projeto (Convenções de doc): os docs de
projeto/sãoNN-titulo.md(duas casas, semPROJ-/ano); avulso vai emprojeto/diversos.md. A seção no site chama-se "Etapas do Projeto". - Público/privado (Convenções de doc):
docs/é privado por padrão; o público vive emdocs/public/(public/index,public/manual/,public/api/) — uma pasta, sem marcação por página. O manual do usuário e a API exposta moram aí. Guarda: página empublic/não linka para fora depublic/(o validador falha). Enquanto o portal não exige login, o site é um só e serve tudo menosprivado/(Publicar docs). - Referência de API (Níveis de documentação): se o app expõe API, descomente no job
docsdopipeline.ymlo passo "Gerar referência de API" da sua stack — o CI de docs gera do código, antes do build, para dentro dedocs/: Javadoc/dartdoc (interno) →docs/dev/api/(linke com[API Reference](api/index.html)numa páginadev/); OpenAPI (público) →docs/public/api/openapi.yaml+ a páginadocs/public/api/index.md(template)..gitignore:docs/dev/api/edocs/public/api/openapi.yamlsão gerados — ignore-os (junto comsite/).
6. CI de código — o pipeline.yml¶
O CI/CD do app é 100% GitHub Actions, num pipeline.yml único à la carte
(decisão 0027): um job decide liga gate / docs /
build_* / deploy por evento (push/PR por path — docs-only publica sem
binário; tag = release, alvos do trailer Deploy: / fallback build.targets;
workflow_dispatch = checkboxes). Os jobs de papel distinto (Definição de pronto):
gate — gate de qualidade (push/PR): roda o gate completo de análise estática + testes da
stack — só testes deixa lint/estilo (checkstyle, analyze) escapar para o master. Por stack:
| Stack | Comando do gate |
|---|---|
| Java/Gradle | ./gradlew check (setup-java + setup-gradle; Testcontainers no docker nativo) |
| Flutter | dart format --output=none --set-exit-if-changed . && flutter analyze && flutter test --exclude-tags golden --coverage (subosito/flutter-action; goldens fora do gate) |
| Dart | dart format --output=none --set-exit-if-changed . && dart analyze && dart test |
| Node | npm run lint && npm test |
App só-script (sem suíte): lint é o piso (sempre); testes cobrem a lógica pura onde existir; não invente suíte para um script trivial.
Contrato de release — rede de segurança do release (push de tag): o último step do gate
roda o valida-release.py (SemVer no manifesto ↔ CHANGELOG ↔ tag). Independe da skill
/xadm-release — pega tag fora-de-banda ou bug da skill.
Template canônico:
templates/pipeline.yml. Aviso de falha = notificação nativa do GitHub (email ao autor) — sem step no YAML, sem secret.Migração (repo com
.forgejo/workflows/): re-derive opipeline.ymlvia/xadm-docs— ela apaga os workflows que o camporemoverdo manifesto lista —, delete.forgejo/workflows/e faça PATCHhas_actions=falseno Forgejo (forgejo.md) — senão o Forgejo lê o.github/e roda o pipeline no dind, falhando.
7. Container — se o app deploya¶
App que sobe no Coolify leva Dockerfile + .dockerignore na raiz desde o primeiro
commit de código (Repo e frontmatter). O gate não builda imagem:
sem o Dockerfile, quem descobre a falta é o deploy.
Server Micronaut nasce native (Engenharia ·
decisão 0033): declare
"build": { "targets": ["native"] } no docs/app.json. Derive o Dockerfile.native de
templates/dockerfile-java-native e mantenha
também o Dockerfile JVM (templates/dockerfile-java) como fallback, com a guarda de paridade entre os
dois no pipeline.yml. Build e deploy seguem a Entrega; jar no
build.targets só com o motivo que a 0033 aceita. Declare também smoke.routes no app.json: o /health e uma rota de cada
classe de credencial que o app serve (Smoke de produção). O par .dockerignore vem de
templates/dockerignore-java; não copie do repo irmão. App Java/Gradle leva junto o
.gitattributes (templates/gitattributes-java) — sem ele, checkout Windows deixa o
gradlew com CRLF e o docker build morre com ./gradlew: not found no Alpine. Detalhe
por stack: Java/Micronaut §Deploy.
App Java/Gradle leva também o gradle.properties (templates/gradle.properties) — base
de performance da casa.
App Flutter web ("build": { "targets": ["web"] }) deploya igual, pelos jobs build_web/deploy
do pipeline.yml (web → nginx; publica :web-amd64, deploy = control-plane target=web); onde mora a
config de build-time está em Operação no Coolify.
O Dockerfile web→nginx é receita por app
(o fluxo de sourcemap difere), não template — Flutter §Config.
Leva junto o .gitattributes (templates/gitattributes-flutter): se o Dockerfile web extrai
texto por shell de arquivo versionado (ex. sed da versão no pubspec.yaml), sem ele o \r
do checkout Windows contamina o valor — CI Linux passa, docker build local quebra (mesma classe
do gradlew).
Repo que não deploya (biblioteca, CLI distribuído pela aba Releases) pula este passo.
Repo que era só doc e passou a ter código?¶
Caso comum: o repo entrou no padrão pela documentação (pré-projeto, projeto), o projeto
foi aprovado e virou app. O checklist acima é doc + CI; ao aparecer o primeiro
src/, faltam os passos de código:
pipeline.ymlcom o gate/release da sua stack (passo 6) — sem ele, nada roda em push;has_actions=falseno Forgejo.- Fonte de versão da stack (
gradle.properties/pubspec.yaml) para o contrato de release dogate. Dockerfile+.dockerignore(passo 7) se o app deploya, combuild.targetsesmoke.routesnodocs/app.json.toolchainnodocs/app.json(alimentasetup-java/subositonopipeline.yml; a action resolve a versão no run — 0027)./healthcom shape{status, versao}e o health check (versionamento).docs/dev/guia-do-codigo.mdedocs/dev/como-rodar.md(Níveis de documentação).
O plano do primeiro ciclo de código (/x-planejar) puxa esses itens para a fase de
bootstrap. Deploy não é só "operação humana no painel": a metade que mora no repo é
tarefa de código como qualquer outra.
Migrando de um doc único arc42?¶
Se o app vinha de um doc único arc42 (um index.html com tabela de ADRs), a
migração para os seis níveis é trabalho da skill /xadm-docs. Um
cuidado específico: gere uma tabela de equivalência ADR do arc42 → decisão
NNNN (ex. ADR-004 BYTEA → 0008) na primeira migração — quem conhecia a
numeração antiga não acha a nova sem ela. Barato de fazer uma vez, caro de
reconstruir depois.
Achou brecha no padrão?¶
Se ao aplicar o padrão algo travou, ficou ambíguo ou você decidiu às cegas:
não contorne localmente. Peça ao Claude do seu app um texto descrevendo
o problema e cole-o numa sessão do Claude Code no repo central
documentacao — a correção sai de lá, para todos
(Feedback).