Pular para o conteúdo

Esquema de ADR

Todo ADR do Archgate é um arquivo Markdown armazenado em .archgate/adrs/ com frontmatter YAML que define a identidade e o escopo da decisão. Esta página documenta o esquema do frontmatter, a estrutura das seções markdown e o comportamento de validação.

O bloco de frontmatter YAML fica entre delimitadores --- no topo do arquivo.

---
id: ARCH-001
title: Command Structure
domain: architecture
rules: true
files: ["src/commands/**/*.ts"]
---
CampoTipoObrigatórioDescrição
idstringSimIdentificador único. Não pode ser vazio. Convenção: PREFIX-NNN (ex.: ARCH-001).
titlestringSimTítulo legível da decisão. Não pode ser vazio.
domainstringSimNome de domínio registrado em kebab-case minúsculo. Integrados: backend, frontend, data, architecture, general. Domínios personalizados são aqueles registrados via archgate adr domain add.
rulesbooleanSimSe este ADR possui um arquivo .rules.ts complementar com verificações automatizadas.
filesstring[]NãoPadrões glob que definem o escopo de quais arquivos as regras se aplicam.

O identificador do ADR. Por convenção, usa o prefixo do domínio seguido de um número de sequência com preenchimento de zeros (ex.: ARCH-001, BE-003). O comando archgate adr create gera IDs automaticamente.

Qualquer string não vazia é válida, mas seguir a convenção de prefixo mantém os ADRs organizados e ordenáveis.

Um nome curto e descritivo para a decisão arquitetural. Exibido na saída de archgate adr list e usado como cabeçalho quando agentes de IA referenciam o ADR.

Agrupa ADRs relacionados. O domínio também determina o prefixo do ID usado por archgate adr create.

Projetos podem estender o conjunto integrado com domínios personalizados via archgate adr domain add. Os mapeamentos de domínio → prefixo personalizados ficam em .archgate/config.json e são mesclados com os integrados no momento da leitura.

Defina como true quando este ADR tem um arquivo .rules.ts complementar. Quando archgate check é executado, ele pula ADRs onde rules é false.

Um array opcional de padrões glob que definem o escopo de cobertura de arquivos da regra. Quando presente, ctx.scopedFiles no arquivo de regras contém apenas arquivos que correspondem a esses padrões. Quando ausente, todos os arquivos do projeto estão no escopo.

files: ["src/commands/**/*.ts"]

Múltiplos padrões podem ser especificados:

files: ["src/api/**/*.ts", "src/middleware/**/*.ts"]

Cada domínio mapeia para um prefixo usado na convenção de ID do ADR.

DomínioPrefixoID de Exemplo
backendBEBE-001
frontendFEFE-001
dataDATADATA-001
architectureARCHARCH-001
generalGENGEN-001

O comando archgate adr create usa esse mapeamento para gerar IDs automaticamente.

Projetos podem registrar mapeamentos adicionais de domínio → prefixo via archgate adr domain add. Uma vez registrados, domínios personalizados se comportam como integrados: archgate adr create --domain <nome> gera IDs automaticamente usando o prefixo associado, e ADRs com domínios personalizados são analisados sem erros.

Veja a página de conceitos de Domínios para orientação sobre quando introduzir um domínio personalizado.


Os arquivos de ADR seguem uma convenção de nomenclatura que codifica o ID e um slug legível:

{ID}-{slug}.md # The document
{ID}-{slug}.rules.ts # The companion rules file (optional)

Por exemplo:

ARCH-001-command-structure.md
ARCH-001-command-structure.rules.ts

O slug é uma versão kebab-case do título, gerada automaticamente por archgate adr create.


Após o frontmatter, o corpo do ADR segue uma estrutura de seções padrão. Embora o Archgate não imponha seções específicas, a estrutura a seguir é recomendada para consistência.

Descreve o problema ou situação que motivou a decisão. Inclua alternativas que foram consideradas e por que foram rejeitadas.

## Context
The CLI returns errors in inconsistent formats. Some commands print raw
stack traces, others print nothing, and a few use `console.error()` with
custom formatting.
**Alternatives considered:**
- **No standard** -- Let each command handle errors its own way. Simple
but leads to an inconsistent user experience.
- **Try/catch wrapper** -- A global try/catch at the CLI entry point.
Loses context about which command failed.

Declara a decisão em si e suas principais restrições. Esta é a seção principal que os agentes de IA leem antes de escrever código.

## Decision
All commands MUST use `logError()` from `src/helpers/log.ts` for error
output. Commands MUST NOT call `console.error()` directly.

Orientação concreta e acionável dividida em duas subseções. Funciona como um checklist de referência rápida para desenvolvedores e agentes de IA.

## Do's and Don'ts
### Do
- Use `logError(message, detail?)` for all error output
- Include a suggested fix in the detail parameter when possible
- Exit with code 1 for user errors, code 2 for internal errors
### Don't
- Don't call `console.error()` directly in command files
- Don't print stack traces to users
- Don't exit without printing an error message first

Dividida em três subseções que documentam os tradeoffs.

## Consequences
### Positive
- Consistent error formatting across all commands
- Machine-parseable error output when combined with `--json`
### Negative
- Requires importing `logError` in every command file
- Cannot use built-in error formatting from libraries
### Risks
- New contributors may use `console.error()` by habit. Mitigated by the
automated rule that scans for direct `console.error()` calls.

Descreve como a decisão é aplicada por meio de regras automatizadas e revisão manual.

## Compliance and Enforcement
### Automated Enforcement
- **Archgate rule** ARCH-002/no-console-error: Scans command files for
`console.error()` calls. Severity: error.
### Manual Enforcement
Code reviewers MUST verify:
1. Error messages are actionable and include context
2. Exit codes match the error type (1 for user, 2 for internal)

Links para ADRs relacionados, documentação externa ou documentos de design.

## References
- [ARCH-001 -- Command Structure](./ARCH-001-command-structure.md)
- [Node.js process.exit documentation](https://nodejs.org/api/process.html#processexitcode)

Quando rules: true, o Archgate procura um arquivo complementar com o mesmo nome mas extensão .rules.ts.

ARCH-002-error-handling.md # rules: true in frontmatter
ARCH-002-error-handling.rules.ts # companion rules file

O arquivo de regras deve exportar um RuleSet padrão usando um objeto simples com satisfies RuleSet:

/// <reference path="../rules.d.ts" />
export default {
rules: {
"no-console-error": {
description: "Use logError() instead of console.error()",
async check(ctx) {
for (const file of ctx.scopedFiles) {
const matches = await ctx.grep(file, /console\.error\(/);
for (const match of matches) {
ctx.report.violation({
message: "Use logError() instead of console.error()",
file: match.file,
line: match.line,
fix: "Import logError from src/helpers/log and use it instead",
});
}
}
},
},
},
} satisfies RuleSet;

Consulte a API de Regras para a referência completa da API TypeScript.


O frontmatter YAML é validado no momento do parse usando um esquema Zod. Frontmatter inválido causa um erro de parse com uma mensagem descritiva.

Se um campo obrigatório estiver ausente, o ADR falha no parse:

Invalid ADR frontmatter in ARCH-001-example.md:
- domain: Required

Se domain não for um identificador kebab-case válido (ex.: tem letras maiúsculas ou espaços):

Invalid ADR frontmatter in ARCH-001-example.md:
- domain: domain must be lowercase kebab-case (e.g. 'backend', 'ml-ops')

Observação: o parser aceita qualquer nome que corresponda ao padrão kebab-case. Se um nome específico é “conhecido” pelo projeto — e portanto tem um prefixo que archgate adr create pode usar — depende do conjunto integrado mais quaisquer domínios personalizados registrados via archgate adr domain add. Criar um ADR com um nome de domínio não registrado falha com um erro “Unknown ADR domain” que sugere executar archgate adr domain add.

Se rules for uma string em vez de um booleano:

Invalid ADR frontmatter in ARCH-001-example.md:
- rules: Expected boolean, received string

ADRs que falham na validação são ignorados por archgate check e reportados como erros.