CORTEX · doc

Contrato da Fonte de Documentação

5 regras · v1.1.0 · rascunho · owner: plataforma · 12 KB · doc-contract · sumário em JSON

CORTEX — Contrato da Fonte de Documentação

Versão: 1.1.0 · Data: 2026-10-14 · Status: Rascunho · Owner: Plataforma Caminho canônico: cortex-docs/meta/DOC_SOURCE_CONTRACT.md

Este documento define como os documentos do cortex-docs são estruturados na fonte para serem consumidos por vários canais a partir de uma verdade só: leitura humana online (HTTP), consulta por IA (MCP, "conteúdo certo no ponto certo") e, depois, treino de devs (RAG sobre o próprio corpus). A fonte é o markdown; os consumidores leem metadados estáveis que este contrato fixa. Rascunho pendente de revisão.

A documentação é tratada como dado endereçável registro a registro — mesmo princípio do RAG (cortex-docs/architecture/RAG_AND_INGESTION.md): cada regra é uma unidade com identidade estável, recuperável isoladamente.


1. Front-matter por documento (Obrigatório)

Todo documento abre com front-matter YAML (entre ---), máquina-legível, antes do título humano. O cabeçalho em blockquote (>) é mantido para leitura humana e, a prazo, pode ser gerado do front-matter.

Campo Tipo Função
id slug Identidade do documento (= slug_namespace). Estável, kebab-case, inglês.
title string Título humano.
version semver Igual ao cabeçalho. Coerente com a governança do doc (UNISCALE §31.1).
date YYYY-MM-DD Data da versão.
status enum rascunho | em-evolucao | estavel. Vocabulário fechado.
owner slug Responsável (plataforma).
canonical_path path Caminho canônico — fonte única (UNISCALE §31.5).
slug_namespace slug Prefixo dos slugs de regra deste doc (geralmente = id).
siblings lista de paths Documentos irmãos.

O front-matter tem de ser YAML válido. Em particular, valor que contenha : (dois-pontos seguido de espaço) vai entre aspas — title: "CORTEX — crm-connector (janela de gestão: cards no CRM)". Sem as aspas, o YAML lê o : como separador de mapa e o bloco inteiro fica ilegível; o serviço de documentação pula o doc e serve o índice sem ele, calado (foi o que houve com o CRM_CONNECTOR.md v0.2.0). O linter da fonte parseia o bloco com yaml.safe_load e reprova, com arquivo, linha e coluna — título com dois-pontos é natural em português, então o gate tem de pegar.

2. Slug de regra (Obrigatório)

Cada regra/seção endereçável recebe um slug nominal estável:

<namespace>.<area>.<conceito>
  • kebab-case, inglês (UNISCALE §2, §4). O slug é identificador técnico, não prosa.
  • namespace — vem do front-matter do doc. Namespaces estáveis: uniscale, ecosystem, rag, doc.
  • area — agrupamento fechado por namespace (tabela abaixo). Área nova só com atualização deste contrato.
  • conceito — a regra específica (point-id, casing, event-envelope).

Áreas fixas por namespace:

Namespace Áreas
uniscale naming, types, columns, constraints, lineage, qdrant, mongo, events, service-internals, git, governance, data-architecture
rag principles, data-model, qdrant, outbox, boleto
ecosystem ownership, services, communication, connectors, external-platforms
doc frontmatter, slug, rule, consumers

rag é narrativo/design e hoje não carrega @rule. O ecosystem passou a carregar @rule em docs dedicados de serviço/connector — área services (STORAGE_SERVICE.md, PAYMENT_SERVICE.md) e área connectors (CONNECTORS.md) — enquanto o doc narrativo ECOSYSTEM.md em si segue sem marcadores. As demais áreas ficam reservadas para quando uma regra de nível for promovida ali.

Exemplos: uniscale.qdrant.point-id, uniscale.naming.casing, rag.outbox.sync, doc.slug.grammar.

3. Marcador de regra (Obrigatório)

Logo abaixo do título da seção, um comentário HTML (invisível no render, parseável no build):

### 26.3. Identidade do point (Obrigatório)
<!-- @rule id=uniscale.qdrant.point-id level=obrigatorio since=2.0.0 -->

Campos do marcador:

Campo Obrigatório? Valor
id sim O slug (seção 2).
level sim obrigatorio | recomendado | permitido (espelha o rótulo humano).
since sim Versão do doc em que a regra surgiu.
status não active (default) | deprecated | superseded-by=<slug>.

Escopo (Obrigatório): recebem @rule apenas as seções cujo título declara nível Obrigatório ou Recomendado — ou cujo marcador traz status=deprecated / superseded-by=<slug>, caso em que o título dispensa rótulo de nível (a §4 exige que o slug aposentado siga marcado, e o título de uma regra substituída anuncia (Substituída), não o nível que ela tinha). Seções informativas, intros de seção e nível Permitido não recebem marcador — não são regras endereçáveis.

O sentinela @rule torna os marcadores greppáveis e delimita o início lógico de cada regra (o "chunk" da regra vai do marcador até o próximo título de mesmo nível).

4. Estabilidade do slug (Obrigatório)

  • Slug publicado é imutável. Pode-se renumerar a seção (§26.3 → §27.1) ou reescrever o título e o texto — o slug não muda. O número é humano; o slug é a chave de máquina.
  • Slug nunca é reusado. Regra removida/fundida/dividida marca o slug antigo status=deprecated (ou superseded-by=<novo-slug>), nunca o aponta para outra coisa.
  • Referência cruzada migra para slug ao longo do tempo. Hoje os docs citam "seção 31.3"; o canal de máquina (MCP) chaveia por slug. Citações humanas por número continuam válidas até a migração.

5. Como os consumidores usam (Permitido — informativo)

  • HTTP (humano): o build renderiza cada regra com âncora = slug → link profundo estável (/uniscale#uniscale.qdrant.point-id).
  • MCP (IA): get_rule("uniscale.qdrant.point-id") devolve texto + level + version; list_rules(namespace, level) filtra (ex.: só obrigatorio); search_docs(query) retorna slugs.
  • Treino (RAG): cada bloco @rule é um chunk natural — ingestão por regra, com o slug como identidade preservada (RAG_AND_INGESTION §3.2/§4.1). Documentação reaproveita o pipeline do produto.

6. Marcador de seção @section (âncora estável em doc narrativo) (Obrigatório)

A âncora de uma seção é derivada do texto do título: renomear ou renumerar o título muda a âncora, e nada avisa (título repetido ainda recebe sufixo posicional, então inserir uma seção no meio redistribui os sufixos das seguintes). Em doc narrativo (ecosystem, rag) não há @rule — a âncora de seção é a única forma de endereçar aquele conteúdo. Com get_section(doc_id, anchor) na face MCP, a âncora deixou de ser só fragmento de URL e virou chave de máquina, igual ao slug — e uma reescrita de título a invalida em silêncio (o mesmo sintoma que a §4 existe para impedir).

O marcador resolve, no espírito do @rule:

## 3. Glossário de fronteira: de quem é cada coisa
<!-- @section id=ecosystem.map.glossary -->
  • Opcional, só nas seções citáveis. Onde não houver @section, a âncora derivada do título segue valendo — nada quebra por omissão.
  • Gramática do id: <namespace>.<area>.<conceito>, kebab-case, inglês, com namespace == slug_namespace do doc. Diferente do slug de regra (§2), a area é LIVRE — não presa à tabela fechada da §2, que foi desenhada para regra, não para seção narrativa (daí ecosystem.map.glossary, com map que não é área de regra).
  • Estável como o slug (§4): id imutável e nunca reusado; renumerar ou reescrever o título não muda o id. A unicidade é global, no mesmo espaço dos slugs de @rule — um @section nunca colide com um @rule.
  • Não é regra: @section não carrega level/since, não exige título de nível, não entra na contagem de @rule nem na exigência da §3 de "todo título Obrigatório/Recomendado tem marcador".
  • Consumo: o parser usa o @section como âncora quando presente e cai no título derivado onde não houver — âncora antiga continua funcionando.

Exemplo aplicado

Antes (humano puro):

### 26.3. Identidade do point (Obrigatório)
- O `id` do point é o `id` (UUIDv7) do chunk no Postgres...

Depois (humano + máquina):

### 26.3. Identidade do point (Obrigatório)
<!-- @rule id=uniscale.qdrant.point-id level=obrigatorio since=2.0.0 -->
- O `id` do point é o `id` (UUIDv7) do chunk no Postgres...

Nada muda na renderização humana; o build passa a saber que aquilo é a regra uniscale.qdrant.point-id, obrigatória, desde a 2.0.0.


CHANGELOG

Versão Data Autor Resumo
1.1.0 2026-10-14 Plataforma Dois pedidos de formato da sessão do docs-service. §6 nova (doc.rule.section-marker): marcador @section id=... dá âncora estável a seção narrativa (ecosystem/rag), no espírito do @rule — necessário porque a face MCP passou a servir get_section(doc_id, anchor) e a âncora derivada do título quebrava deep-link em silêncio ao renomear/renumerar. id em espaço próprio: formato <namespace>.<area>.<conceito> e namespace do doc, mas área LIVRE (não presa à tabela fechada da §2, que é para regra), imutável/nunca reusado (§4) e único no mesmo espaço dos @rule; opcional (só seções citáveis), não é regra (sem level/since/título de nível). §1 (esclarecimento): valor de front-matter com : tem de ir entre aspas — sem isso o YAML fica ilegível e o indexador pula o doc calado (incidente do CRM_CONNECTOR.md v0.2.0); o linter passa a parsear o bloco com yaml.safe_load e reprovar com arquivo/linha/coluna. MINOR.
1.0.3 2026-09-10 Plataforma Resolve tensão entre a §3 e a §4: a §4 (doc.slug.stability) manda a regra aposentada seguir marcada (deprecated/superseded-by=), mas o escopo da §3 só admitia marcador sob título que declara Obrigatório/Recomendado — e o título de uma regra substituída anuncia (Substituída). Obedecer a uma violava a outra (ecosystem.services.tracking-merge-alias, TRACKING_SERVICE §15-bis). A §3 passa a admitir marcador sem rótulo de nível no título quando o status é de regra aposentada. Nenhuma regra ativa muda; o linter da fonte acompanha. PATCH.
1.0.2 2026-06-15 Plataforma Atualiza a nota da §2 (grammar): o namespace ecosystem deixou de ser "sem @rule" — passou a carregar regras via docs dedicados, na área services (storage-service, payment-service) e na área connectors, enquanto o ECOSYSTEM.md narrativo segue sem marcadores. Correção de fato na prosa informativa; nenhuma regra @rule alterada. PATCH.
1.0.1 2026-06-02 Plataforma Corrige inconsistência da própria fonte: remove o marcador @rule da §5 (doc.consumers.usage), que era nível Permitido e portanto não deveria ter marcador pela regra de escopo da §3. PATCH.
1.0.0 2026-06-02 Plataforma Contrato inicial da fonte de documentação: front-matter YAML por documento, slug nominal estável por regra (<namespace>.<area>.<conceito>), marcador @rule (comentário HTML com id/level/since/status), regras de estabilidade do slug (imutável, nunca reusado, renumeração não afeta) e mapa de consumo (HTTP humano, MCP para IA, RAG de treino por regra). Rascunho pendente de revisão.