Manutenção e Publicação de Documentação
Regra: documento sem link na sidebar = documento inexistente.
Toda documentação nova DEVE ser visível na navegação lateral do VitePress.
1. Checklist Obrigatório para Novo Documento
Cada novo arquivo .md em docs/ exige todas as etapas abaixo na mesma entrega:
- [ ] Arquivo
.mdcriado emdocs/<seção>/com nomeUPPER_SNAKE_CASE.md - [ ] Entry adicionada em
docs/.vitepress/config.tsna seção correta da sidebar - [ ] Entry adicionada em
docs/README.mdna tabela-índice da seção correspondente - [ ] Se é regra obrigatória → cláusula adicionada ao Knowledge (
project-knowledge) - [ ] Se é padrão recorrente → memory criada para contexto automático
Nenhuma dessas etapas é opcional. Se qualquer uma for esquecida, o documento fica invisível para a navegação, para o AI, ou para ambos.
2. Mapa de Seções
Cada tipo de documento tem um diretório específico. Colocar no lugar certo garante que será encontrado:
| Diretório | Conteúdo | Exemplos |
|---|---|---|
architecture/ | Schemas, diagramas de sistema, decisões de infra. ADRs vivem em architecture/adrs/ | architecture/adrs/ADR-001-…, DATABASE_SCHEMA.md |
architecture/adrs/ | Architecture Decision Records (SSOT de padrões) | ADR-001-supabase-client-factory.md, ADR-011-service-role-vs-rls.md |
security/ | RLS, auth, rate limits, auditorias de segurança, hashing | RLS_DESIGN_GUIDE.md, AUTHENTICATION.md |
development/ | Padrões de código, templates, checklists, guias de dev | CODING_STANDARDS.md, NEW_EDGE_FUNCTION.md |
operations/ | Deploy, cron, troubleshooting, monitoramento | DEPLOYMENT.md, CRON_JOBS.md |
staging/ | Setup e referência do ambiente staging | STAGING_SETUP.md, STAGING_REFERENCE.md |
mural/ | Portal aluno/responsável (Mural Olímpico) | MURAL_OVERVIEW.md, MURAL_LIBERACOES.md |
business/ | Planos, faturamento, assinaturas | SUBSCRIPTION_BILLING.md |
plans/ | Designs futuros não implementados | ANOMALY_DETECTION.md |
audits/ | Relatórios de auditoria pontuais (com data) | AUDIT_CALENDARIO_TRIAL_CADASTRO_2026-03-30.md |
3. Convenções de Nomes
| Regra | Exemplo |
|---|---|
Nome em UPPER_SNAKE_CASE.md | RLS_DESIGN_GUIDE.md |
ADRs em architecture/adrs/ com prefixo ADR-NNN-slug.md | ADR-001-supabase-client-factory.md |
Prefixo AUDIT_ para relatórios de auditoria | AUDIT_CALENDARIO_TRIAL_CADASTRO_2026-03-30.md |
| Data no nome para documentos pontuais | SECURITY_AUDIT_2026-02-28.md |
| Sem espaços, sem acentos, sem caracteres especiais | — |
4. Como Adicionar na Sidebar (config.ts)
O arquivo docs/.vitepress/config.ts contém o array sidebar com seções. Cada seção é um objeto:
{
text: 'Nome da Seção', // título visível
collapsed: false, // false = expandida por padrão
items: [
{ text: 'Título do Doc', link: '/secao/NOME_DO_ARQUIVO' },
// ↑ sem .md, com / inicial
],
}Regras:
- O
linkusa o path relativo à raiz dedocs/, sem a extensão.md - Seções principais (
Arquitetura,Segurança,Desenvolvimento) ficamcollapsed: false - Seções secundárias (
Testes,Staging,Operações, etc.) ficamcollapsed: true - Novos itens vão ao final da lista
itemsda seção, exceto se há ordem lógica clara
5. Como Adicionar no Índice (README.md)
O docs/README.md contém tabelas Markdown organizadas por seção. Cada entrada segue o formato:
| [NOME_DO_ARQUIVO.md](./secao/NOME_DO_ARQUIVO.md) | Descrição curta do conteúdo |Adicionar na tabela da seção correspondente, mantendo a ordem existente.
6. Como o AI Recebe Contexto (3 Camadas)
O Lovable opera com três camadas de contexto. Apenas uma é controlável pelo usuário.
6.1 Camadas de Contexto
| Camada | Visibilidade | Limite | Quem edita | Confiável? |
|---|---|---|---|---|
| Knowledge | Sempre injetado em toda mensagem, sem exceção | 10.000 chars (Project) + 10.000 chars (Workspace) | Usuário manualmente | SIM — fonte de verdade |
| Memories | Selecionadas por relevância; podem ou não aparecer | Sem limite conhecido | Lovable (automático) | NÃO — auxiliar apenas |
| docs/ | Consultados sob demanda — AI precisa ler explicitamente | Sem limite | Usuário ou AI via entrega | SIM — se referenciado |
6.2 Memories (camada automática)
O Lovable gera automaticamente Memories a partir de padrões que emergem das conversas. Elas são metadados internos, não documentação do projeto.
Como funcionam:
- Geradas automaticamente pelo Lovable a partir de padrões recorrentes nas conversas
- Injetadas no bloco
<useful-context>com prefixo<memory/...>antes de cada mensagem - Selecionadas por relevância estimada — NÃO garantidas em toda mensagem
- Sem interface para o usuário visualizar, editar ou deletar
- O usuário não controla quais Memories existem nem quando aparecem
Por que NÃO são confiáveis:
- Podem estar desatualizadas (refletindo decisões antigas já revertidas)
- Podem estar ausentes (o algoritmo de relevância não as selecionou)
- Podem contradizer o Knowledge ou a documentação atual
- Se uma regra depende exclusivamente de uma Memory, ela pode falhar silenciosamente
Regra: toda regra que "o AI aprendeu" via conversa DEVE ser formalizada no Knowledge ou em docs/. Memory nunca substitui documentação explícita.
6.3 Quando Colocar no Knowledge vs. docs/
| Situação | Onde | Por quê |
|---|---|---|
Regra que se aplica a toda interação (ex: "nunca usar FOR ALL") | Knowledge | Precisa estar visível sempre, sem depender de leitura |
| Ponteiro para documento detalhado | Knowledge (1 linha com → Ref: docs/...) | Garante que o AI sabe que o doc existe e quando lê-lo |
| Guia detalhado, template, inventário, relatório | docs/ apenas | Muito grande para Knowledge; consultado quando necessário |
| Regra crítica + detalhes extensos | Knowledge (regra curta) + docs/ (detalhes) | Regra sempre visível, detalhes acessíveis |
| Regra que "o AI já aprendeu" via conversa | Knowledge (não Memory) | Memories podem desaparecer; Knowledge é garantido |
6.4 Boas Práticas para o Knowledge
- Compacto: cada regra em 1-2 linhas. Detalhes vão nos docs.
- Estruturado: usar tabelas e seções com headers claros.
- Ponteiros: toda regra que tem doc detalhado deve ter
→ Ref: docs/... - Tabela de leitura obrigatória: mapear tipo de tarefa → documentos que DEVEM ser lidos antes.
- Sem redundância: não repetir no Knowledge o que já está nos docs — apenas apontar.
- Prioridade: se Knowledge e docs conflitam, Knowledge prevalece. Se Project e Workspace Knowledge conflitam, Project prevalece.
6.5 Limitações Importantes
- O AI não lembra entre sessões. Cada mensagem começa do zero com: Knowledge + Memories (se selecionadas) + código visível + histórico da sessão atual.
- Memories são voláteis e opacas. Nunca assumir que uma Memory será injetada. Toda regra crítica DEVE estar no Knowledge.
- docs/ não são lidos automaticamente. Se uma regra está APENAS em
docs/, o AI pode não consultá-la a menos que o Knowledge instrua explicitamente. - Knowledge tem limite de 10k chars. Regras devem ser concisas. Se o Knowledge está cheio, mover detalhes para docs e deixar apenas ponteiros.
Regra prática: se em dúvida, crie o doc primeiro e adicione uma cláusula curta no Knowledge apontando para ele.
7. Validação
Após adicionar documentação, verificar:
- Sidebar: o documento aparece na navegação lateral?
- Índice: o documento está listado na tabela do README.md?
- Links: os links internos (referências cruzadas) funcionam?
- Build:
npm run docs:buildpassa sem erros de dead links?
# Verificar dead links no build
cd docs && npx vitepress buildDocs Build Guardrails (VitePress) — SSOT
Este documento é o SSOT para tudo que pode quebrar ou poluir o deploy de
docs.olp.digital. Outros docs (DEV_WORKFLOW.md,PROBLEM_SOLVING.md,VITEPRESS_SETUP.md,CI_PIPELINE.md) referenciam esta seção em vez de duplicar regras.O workflow
.github/workflows/docs-validate.ymlrodabun run docs:buildem todo PR que tocadocs/**,package.jsonou o próprio workflow. Build aborta comexit 1em qualquer dos casos abaixo. O CI também é gate de merge paradeploy-docs.yml— falha aqui bloqueia publicação em produção.
Regra de ouro
Antes de abrir PR que toque
docs/**,docs/.vitepress/**, scriptsdocs:*empackage.jsonou os workflowsdocs-validate.yml/deploy-docs.yml: rodarbun run docs:buildlocalmente. Falha local = falha no CI = deploy bloqueado. Sem exceção.
1. Interpolação Vue (mustaches )
VitePress processa markdown como template Vue. Duas chaves seguidas em parágrafo — mesmo dentro de backticks inline — são parseadas como expressão JS e quebram o build com Error parsing JavaScript expression: Unexpected token.
Como escapar ao documentar variáveis de template ({{nome}}, {{link_fatura}}):
- Inline: usar entidades HTML — escreva
{{nome}}no fonte, o leitor vê o mustache literal. - Bloco: usar fenced block com linguagem (
```text,```bash,```html). Dentro do fence o mustache não é parseado. - Não funciona: backticks inline (``) — Vue ainda parseia.
Vale também para exemplos de templates de e-mail/WhatsApp e qualquer placeholder estilo Handlebars.
2. Dead links — ignoreDeadLinks é exceção, não regra
docs/.vitepress/config.ts tem ignoreDeadLinks apenas para .sql e paths legados conhecidos. Não relaxar essa lista para esconder bug — corrigir o link na origem.
Padrões de link:
| Caso | Forma correta | Erro comum |
|---|---|---|
| Arquivo na mesma pasta | [X](./MIGRATION_SAFETY_PROTOCOL.md) | [X](MIGRATION_SAFETY_PROTOCOL) (sem extensão, sem ./) |
| Arquivo em outra pasta | [X](../security/RLS_DESIGN_GUIDE.md) | Caminho errado relativo à pasta do arquivo atual |
| Índice de uma seção (a partir de outro doc qualquer) | [X](/lgpd/) ou [X](/architecture/adrs/) — com barra final, sem index | ❌ [X](/lgpd/index) — VitePress não resolve index manual; rota canônica é '/secao/' |
| Item da sidebar referenciando índice de pasta | link: '/lgpd/' | link: '/lgpd/index' |
| Página específica fora da pasta atual (em audit / plan) | [X](/lgpd/PII_LOG_MASKING_PLAN) (absoluto, sem .md) ou [X](../lgpd/PII_LOG_MASKING_PLAN.md) | Misturar os dois estilos no mesmo arquivo sem motivo |
Regra: após mover/renomear qualquer arquivo, rodar rg "NOME_ANTIGO" docs/ e atualizar todas as referências antes de commitar.
3. Fenced block — allowlist de linguagens
VitePress usa Shiki. Linguagens fora da allowlist caem para txt com warning ruidoso que polui o log de CI e mascara erros reais.
Allowlist do projeto: text, txt, bash, sh, ini, yaml, yml, json, ts, tsx, js, jsx, sql, html, css, md, diff.
Proibido / falsos amigos:
| ❌ Não usar | ✅ Substituir por |
|---|---|
```env | ```bash (variáveis exportadas) ou ```ini (KEY=value) ou ```txt |
```dotenv | idem |
```deno | ```ts ou ```bash |
```supabase | ```sql ou ```bash |
4. Componentes Vue custom em .md
Os componentes em docs/.vitepress/theme/components/*.vue (<BenchmarkChart>, <DecisionTable>, <Roadmap>, <ContingencyBox>, <DocsMetrics>) só funcionam se forem registrados em theme/index.ts. Quebra silenciosa: o build não falha, mas o site renderiza tag literal. Validar visualmente após bun run docs:preview.
5. Sidebar e índice
Toda nova página .md exige, na mesma entrega:
- Entry em
docs/.vitepress/config.ts(sidebar) — usarlink: '/secao/NOME'(sem.md, sem/indexquando for raiz da seção) - Entry em
docs/README.md(tabela-índice da seção) - Se a página é a "home" da seção, criar
docs/<secao>/index.md(e o link na sidebar é'/<secao>/')
Ver §1–§5 acima desta seção operacional.
6. Validação local — comando único
bun run docs:buildEsse é exatamente o comando do CI (docs-validate.yml). Se passa local, passa CI. Se falha local, não abrir PR.
Erros reais já ocorridos (catálogo)
| Caso | Sintoma no CI | Causa raiz | Fix |
|---|---|---|---|
A — /lgpd/index (mai/2026, deploy de docs PII) | Found dead link /lgpd/index in file audits/AUDIT_PII_LOGS_LGPD_2026-05-08.md → Build failed in 14.18s | Link absoluto para "índice de seção" usando /secao/index em vez de /secao/ | Trocar por /lgpd/ (rota canônica do VitePress para o index.md da pasta) |
| B — fenced ```env` (recorrente) | The language 'env' is not loaded, falling back to 'txt' (3+ ocorrências por build) | Uso de env como linguagem de fence em exemplos de variáveis de ambiente | Trocar por bash (export …) ou ini (KEY=value) ou txt |
| C — mustache Vue (jan/2026, templates de e-mail) | Error parsing JavaScript expression: Unexpected token em página de templates | literal no markdown, parseado pelo Vue | Escapar com entidades HTML inline ou colocar em fenced block |
| D — link sem extensão entre arquivos | Found dead link ./MIGRATION_SAFETY_PROTOCOL | Link relativo sem .md | Sempre .md em links relativos entre arquivos |
Padrão de fix: corrigir o markdown fonte. Nunca adicionar regex em
ignoreDeadLinkspara esconder o problema — isso desabilita a validação para casos legítimos futuros.
Checklist final (qualquer alteração em docs/**)
- [ ] Doc adicionado/movido entrou na sidebar (
docs/.vitepress/config.ts)? - [ ] Doc adicionado/movido entrou no índice (
docs/README.md)? - [ ] Links cruzados resolvem (
./ou../com.md; absolutos como/secao/para índice)? - [ ] Nenhum link absoluto usa
/secao/index(use/secao/com barra final)? - [ ] Nenhum fenced block usa linguagem fora da allowlist (especialmente
env)? - [ ] Nenhum mustache Vue (
) literal fora de fenced block ou entidade HTML? - [ ]
bun run docs:buildpassou localmente sem dead link e sem warning evitável?
Resumo
Novo documento = .md + config.ts + README.md + Knowledge (se regra)Sem exceções.