Pular para conteúdo

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ão BI_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-workspace rotula 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.md e, conforme o caso, projeto/ (Etapas), decisoes/, dev/, operacao/, e public/ (manual + API públicos) (crie public/img/ junto com a primeira screenshot — Git não versiona pasta vazia). Repo com código tem dev/guia-do-codigo.md e dev/como-rodar.md obrigatórios (Níveis de documentação); o validador os cobra em app com build.targets.
  • Crie docs/anexos/ e docs/anexos/privado/ com os READMEs canônicos (templates/anexos-readme.md e templates/anexos-privado-readme.md do repo central): anexo público em anexos/, dado real de cliente só em anexos/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.json com os metadados do app — é ele que faz o app aparecer com nome e grupo certos na página Aplicações. O perfil ausente vale app (Perfis de repo); o kit quem grava é a /xadm-docs. App Java/Flutter: declare toolchain (ex. { "java": "25" }) — é obrigatório (o validador falha sem ele). A versão alimenta setup-java/subosito/flutter-action no pipeline.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 bloco features do app.json (build-time). Ver Central de apps.
  • Crie docs/changelog.md a partir de templates/changelog.md — uma linha que embute o CHANGELOG.md da raiz (--8<-- "CHANGELOG.md"); o mkdocs.yml já vem com a entrada de nav "Mudanças". Fonte única: não copie o conteúdo, só o stub.
  • Crie overrides/main.html a partir de templates/overrides-main.html (o mkdocs.yml já aponta theme.custom_dir: overrides) — é o aviso de "versão antiga" do seletor de versão (decisão 0004). O custom_dir exige 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.json constituicao;
  • o kit (templates, scripts, skills) — kit-versao.txt = app.json kit;
  • o site — VERSION, /versao.txt e a tag vX.Y.Z do 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.yml na 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 do CLAUDE.md do 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 hook SessionStart do checa-constituicao.sh (abaixo). Path de máquina fica FORA: se o JDK default da máquina ≠ a toolchain do app, ponha env.JAVA_HOME no .claude/settings.local.json gitignored — senão o agente prefixa JAVA_HOME=… ./gradlew e quebra o allow Bash(./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.md que o manifesto.json lista, exceto as do campo opcionais (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 workflow x-desenhar, x-definir, x-refinar, x-planejar, x-implementar, x-documentar + xadm-meta-audit-work, xadm-docs, xadm-release e xadm-setup (Central de Apps — o passo 2 manda rodá-la depois de codar, antes da release). As x-* são diretórios (templates/<nome>/ com SKILL.md + references/) → copie o diretório inteiro para .claude/skills/<nome>/; as xadm-* são arquivo único (templates/<nome>-skill.md → .claude/skills/<nome>/SKILL.md). Não pare em docs+release: o manifesto.json é a lista mecânica completa — cruze com ele, não com esta prosa. Duas skills têm passo extra:
    • xadm-docs — copie também templates/checa-constituicao.sh → .claude/checa-constituicao.sh e crave o hook SessionStart no .claude/settings.json (obrigatório — o templates/settings.json traz só env+permissions, então sem cravar o hook o .sh fica presente porém nunca acionado; o bloco está no topo do script). Preencha constituicao e kit no docs/app.json com as versões vigentes (Versões); o CLAUDE.md aponta 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. O CHANGELOG.md não se cria à mão — nasce na primeira /xadm-release (infere do git log e 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 --strict e 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", o app.json nã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 campo entrega: + 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.md a 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ém projeto/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ão NN-titulo.md (duas casas, sem PROJ-/ano); avulso vai em projeto/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 em docs/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 em public/ não linka para fora de public/ (o validador falha). Enquanto o portal não exige login, o site é um só e serve tudo menos privado/ (Publicar docs).
  • Referência de API (Níveis de documentação): se o app expõe API, descomente no job docs do pipeline.yml o passo "Gerar referência de API" da sua stack — o CI de docs gera do código, antes do build, para dentro de docs/: Javadoc/dartdoc (interno) → docs/dev/api/ (linke com [API Reference](api/index.html) numa página dev/); OpenAPI (público) → docs/public/api/openapi.yaml + a página docs/public/api/index.md (template). .gitignore: docs/dev/api/ e docs/public/api/openapi.yaml são gerados — ignore-os (junto com site/).

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 o pipeline.yml via /xadm-docs — ela apaga os workflows que o campo remover do manifesto lista —, delete .forgejo/workflows/ e faça PATCH has_actions=false no 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:

  1. pipeline.yml com o gate/release da sua stack (passo 6) — sem ele, nada roda em push;
  2. has_actions=false no Forgejo.
  3. Fonte de versão da stack (gradle.properties/pubspec.yaml) para o contrato de release do gate.
  4. Dockerfile + .dockerignore (passo 7) se o app deploya, com build.targets e smoke.routes no docs/app.json.
  5. toolchain no docs/app.json (alimenta setup-java/subosito no pipeline.yml; a action resolve a versão no run — 0027).
  6. /health com shape {status, versao} e o health check (versionamento).
  7. docs/dev/guia-do-codigo.md e docs/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).