Menu
Testar no Playground

Diagnósticos em JSON do Zero: erros estruturados para agentes

O compilador Zero emite diagnósticos em JSON legíveis por máquina, com códigos de erro estáveis e planos de reparo estruturados. Veja o formato, por que existe e como um agente consome.

A funcionalidade de destaque

A funcionalidade mais distintiva do Zero não é um pedaço de sintaxe. É a forma como o compilador conversa com quem — ou o que — está lendo sua saída.

Passe um programa quebrado pelo zero check --json e você recebe um feed que um agente lê diretamente:

{
    "ok": false,
    "diagnostics": [
        {
            "code": "NAM003",
            "message": "unknown identifier",
            "line": 3,
            "repair": { "id": "declare-missing-symbol" }
        }
    ]
}

É um blob pequeno, mas carregado. Vamos desempacotar cada campo e as escolhas de design por trás deles.

A anatomia de um diagnóstico

Um diagnóstico é um objeto estruturado que descreve um problema no código-fonte. Os campos canônicos:

  • code — um identificador estável (por exemplo, NAM003). Sempre significa a mesma coisa, independente da versão do compilador.
  • message — uma descrição legível para humanos. A redação pode mudar entre versões; o significado é fixado pelo code, não pela mensagem.
  • line (e outros campos de localização) — onde está o problema.
  • repair — metadados estruturados opcionais descrevendo uma correção que o compilador acha que resolveria o diagnóstico. A forma desse campo também é documentada e estável.

A forma de nível superior inclui um booleano ok para a execução como um todo e um array diagnostics; mesmo quando a execução é bem-sucedida, o array pode conter avisos ou notas.

Códigos de erro estáveis

O contrato no code é a parte que provavelmente vai te surpreender. NAM003 hoje significa "identificador desconhecido". NAM003 no mês que vem e no ano que vem também vai significar "identificador desconhecido". Agentes (e humanos) podem confiar nisso.

Isso importa porque modelos de linguagem e ferramentas tendem a cachear ou memorizar o que viram. Se o significado de NAM003 mudasse a cada release, toda consulta em cache seria insegura. Fixar o código mantém:

  • Dados de treinamento de agentes válidos entre versões.
  • Documentação indexável por código.
  • Pipelines de ferramentas estáveis.

A message legível para humanos é livre para mudar conforme o time melhora a redação. O code é o identificador que sustenta tudo.

Metadados de reparo

O campo repair, quando presente, diz ao consumidor que tipo de correção o compilador acha que funcionaria:

{
    "code": "NAM003",
    "message": "unknown identifier",
    "line": 3,
    "repair": { "id": "declare-missing-symbol" }
}

declare-missing-symbol aqui é o tipo de reparo — a intenção em alto nível. Para conseguir as edições propriamente ditas, chame zero fix --plan --json. Ele retorna um plano que inclui o caminho do arquivo, os intervalos em bytes a modificar e o novo texto:

{
    "diagnostic": { "code": "NAM003", "line": 3 },
    "plan": {
        "id": "declare-missing-symbol",
        "edits": [
            { "kind": "insert", "line": 1, "text": "fun answer() -> i32 { return 42 }\n" }
        ]
    }
}

(Os nomes e a forma exata dos campos podem variar na versão da sua toolchain — o princípio é "dado estruturado, não prosa".)

Um agente lendo o plano tem algumas opções:

  1. Aplicar as edições como estão.
  2. Aplicar as edições com modificações.
  3. Rejeitar o plano e buscar outra correção.

Em todos os casos, o agente está operando em dado estruturado em vez de tentar interpretar uma sugestão em inglês. É essa a diferença entre planos de reparo e as dicas de "você quis dizer ...?" de um compilador típico.

Como um agente realmente usa isso

Um loop simplificado de ponta a ponta que um agente pode rodar:

  1. Gerar ou modificar um arquivo Zero.
  2. Rodar zero check --json em cima.
  3. Se o resultado for { "ok": true, ... }, seguir em frente.
  4. Caso contrário, para cada diagnóstico:
    • Consultar o code para entender o que está errado (com zero explain ou uma tabela local).
    • Se um repair for oferecido e parecer seguro, chamar zero fix --plan --json para as edições.
    • Aplicar (ou simular) as edições.
  5. Voltar para o passo 2.

Compare com trabalhar a partir de uma mensagem em prosa: o agente teria que parsear inglês, extrair um número de linha provável, adivinhar o tipo de correção e inferir o texto exato de inserção ou substituição. Cada passo é nebuloso. O caminho via JSON troca cada passo por uma consulta a um schema documentado.

Além de erros: grafo e tamanho

--json não é só para diagnósticos. Outros comandos expõem dado estruturado do mesmo jeito:

  • zero graph --json — emite o grafo de dependências de um pacote como dado estruturado. Útil para entender o que depende do quê, e para agentes que querem raciocinar sobre pontos de chamada antes de mexer.
  • zero size --json — relata o tamanho em disco dos artefatos compilados, dividido por alvo. O dado é o mesmo que os humanos veem em zero size, só que parseável.

Essas formas são parte do design: sempre que o compilador tem dado útil, ele está disponível como JSON para ferramentas consumirem sem fazer scraping de tela.

Como é o schema

Os nomes dos campos e as formas exatas estão documentados no repositório do Zero e vão evoluir enquanto o projeto for pré-1.0. As categorias que você pode esperar:

  • Metadados da execuçãook, version, tempos.
  • Diagnósticoscode, message, localização (arquivo/linha/coluna/intervalos em bytes), severidade (error/warning/note), repair opcional.
  • Planos de reparo — quando buscados, a lista estruturada de edições.

Se você está construindo ferramentas sobre essa superfície, o padrão seguro é ler os campos que você conhece, ignorar campos desconhecidos com elegância e usar o code como chave para decisões comportamentais.

Um passo a passo rápido de ponta a ponta

Suponha que seu código-fonte use um identificador que não está declarado:

pub fun main(world: World) -> Void raises {
    check world.out.write(answer())   // 'answer' não está definido em lugar nenhum
}

Rodar zero check --json produz algo como:

{
    "ok": false,
    "diagnostics": [
        {
            "code": "NAM003",
            "message": "unknown identifier 'answer'",
            "line": 2,
            "column": 27,
            "repair": { "id": "declare-missing-symbol" }
        }
    ]
}

zero fix --plan --json retorna a edição:

{
    "diagnostic": { "code": "NAM003", "line": 2 },
    "plan": {
        "id": "declare-missing-symbol",
        "edits": [
            { "kind": "insert", "line": 1, "text": "fun answer() -> i32 { return 42 }\n" }
        ]
    }
}

zero fix (sem --plan) aplica a edição direto, e depois disso zero check retorna ok: true. Cada passo é uma transação discreta e inspecionável.

Por que isso importa além dos agentes

As mesmas propriedades — saída estruturada, códigos estáveis, planos de reparo — também tornam a vida mais fácil para:

  • Editores e IDEs. Sublinhados e lâmpadas que agem sobre IDs de repair em vez de texto parseado.
  • Pipelines de CI. Falhas logadas com o code para grep fácil e dashboards.
  • Ferramentas de code-mod. Correções em massa que miram um code, não um regex em mensagens.

O sistema foi desenhado pensando em agentes, mas as ferramentas voltadas para humanos ganham os mesmos benefícios.

A seguir: Design Agent-First

O sistema de diagnósticos é o exemplo mais concreto da filosofia agent-first do Zero. A próxima documentação, design agent-first, volta o foco para os princípios subjacentes — superfície pequena, ferramentas determinísticas, efeitos explícitos — e como cada um ganha seu lugar.

Perguntas frequentes

O que são diagnósticos em JSON no Zero?

Quando você roda zero check --json (ou outros comandos com --json), o compilador emite suas constatações como JSON estruturado em vez de prosa formatada para humanos. Cada diagnóstico carrega um código de erro estável como NAM003, a localização no código-fonte, uma mensagem legível para humanos e — quando aplicável — um campo repair estruturado descrevendo como corrigir.

Por que o Zero emite JSON em vez de texto puro?

Agentes precisam parsear a saída do compilador. Diagnósticos em texto puro são escritos para humanos e exigem regex sobre inglês para extrair um número de linha ou adivinhar uma correção. JSON é inequívoco: um agente lê o campo code, consulta o significado documentado e age sobre o plano repair estruturado, sem nunca interpretar prosa.

O que é um código de erro estável no Zero?

Cada diagnóstico que o compilador pode emitir tem um identificador curto e estável como NAM003 (identificador desconhecido). O contrato é que o código mantém o significado entre versões do compilador, mesmo que a redação da mensagem para humanos mude. Agentes e ferramentas podem fazer pattern matching no código sem se preocupar com mudança de mensagem.

O que é um plano de reparo?

Quando o compilador acha que sabe como corrigir um diagnóstico, ele anexa um campo repair estruturado nomeando o tipo de correção que proporia. Chamar zero fix --plan --json retorna o plano completo — as operações de edição a aplicar, os arquivos e intervalos afetados. Um agente pode aplicar, modificar ou rejeitar o plano de forma programática.

Qual a relação entre zero explain e os diagnósticos em JSON?

zero explain <code> retorna a explicação legível para humanos de um código de diagnóstico — o que o erro significa, por que o compilador o lança e correções típicas. É o lado em prosa do diagnóstico. O código é estável, então explicações em cache continuam válidas; agentes buscam quando um código sai do escopo dos dados de treinamento.

Coddy programming languages illustration

Aprenda a programar com o Coddy

COMEÇAR