Menu

Zero JSON-Diagnostik: Strukturierte Compiler-Fehler für Agenten

Zeros Compiler gibt maschinenlesbare JSON-Diagnostik mit stabilen Fehlercodes und strukturierten Repair-Plänen aus. Hier das Format, warum es existiert und wie ein Agent es konsumiert.

Das Schlagzeilen-Feature

Das markanteste Feature von Zero ist kein Syntax-Element. Es ist die Art, wie der Compiler mit demjenigen – oder dem Etwas – spricht, das seine Ausgabe liest.

Lass ein kaputtes Programm durch zero check --json laufen und du bekommst einen Feed, den ein Agent direkt lesen kann:

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

Das ist ein kleiner, aber dichter Blob. Packen wir jedes Feld und die Designentscheidungen dahinter aus.

Die Anatomie einer Diagnostik

Eine Diagnostik ist ein strukturiertes Objekt, das ein Problem im Quellcode beschreibt. Die kanonischen Felder:

  • code – ein stabiler Identifier (z. B. NAM003). Bedeutet immer dasselbe, unabhängig von der Compiler-Version.
  • message – eine menschenlesbare Beschreibung. Die Formulierung kann sich über Versionen ändern; die Bedeutung ist durch code festgenagelt, nicht durch die Meldung.
  • line (und weitere Positionsfelder) – wo das Problem ist.
  • repair – optionale strukturierte Metadaten, die einen Fix beschreiben, von dem der Compiler glaubt, dass er die Diagnostik beheben würde. Die Form dieses Feldes ist selbst dokumentiert und stabil.

Die Top-Level-Form enthält ein ok-Boolean für den Lauf als Ganzes und ein diagnostics-Array; auch wenn der Lauf erfolgreich ist, kann das Array Warnungen oder Hinweise enthalten.

Stabile Fehlercodes

Der Vertrag bei code ist der Teil, der dich am ehesten überrascht. NAM003 heißt heute „unknown identifier". NAM003 wird auch nächsten Monat und nächstes Jahr „unknown identifier" heißen. Agenten (und Menschen) können sich darauf verlassen.

Das ist wichtig, weil Sprachmodelle und Tooling dazu neigen, Gesehenes zu cachen oder sich zu merken. Würde sich die Bedeutung von NAM003 mit jedem Release verschieben, wäre jeder gecachte Lookup unsicher. Den Code zu pinnen hält:

  • Agenten-Trainingsdaten über Versionen hinweg gültig.
  • Dokumentation indexierbar nach Code.
  • Tooling-Pipelines stabil.

Die menschenlesbare message darf sich ändern, wenn das Team die Formulierungen verbessert. Der code ist der tragende Identifier.

Repair-Metadaten

Das repair-Feld sagt, wenn vorhanden, dem Konsumenten, welche Art Fix der Compiler für tragfähig hält:

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

declare-missing-symbol ist hier die Art des Repairs – die übergeordnete Absicht. Um die eigentlichen Edits zu bekommen, ruf zero fix --plan --json auf. Das liefert einen Plan zurück, der den Dateipfad, die zu ändernden Byte-Bereiche und den neuen Text enthält:

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

(Die genauen Feldnamen und die Form können sich in deiner Toolchain-Version unterscheiden – das Prinzip ist „strukturierte Daten, keine Prosa".)

Ein Agent, der den Plan liest, hat ein paar Wahlmöglichkeiten:

  1. Die Edits unverändert anwenden.
  2. Die Edits mit Modifikationen anwenden.
  3. Den Plan verwerfen und nach einem anderen Fix greifen.

In jedem Fall arbeitet der Agent auf strukturierten Daten, statt zu versuchen, einen englischen Vorschlag zu interpretieren. Das ist der Unterschied zwischen Repair-Plänen und den „meintest du …?"-Hinweisen in einem typischen Compiler.

Wie ein Agent das tatsächlich nutzt

Eine vereinfachte End-to-End-Schleife, die ein Agent ausführen könnte:

  1. Eine Zero-Datei generieren oder ändern.
  2. zero check --json dagegen ausführen.
  3. Ist das Ergebnis { "ok": true, ... }, weitermachen.
  4. Sonst für jede Diagnostik:
    • Den code nachschlagen, um zu verstehen, was falsch ist (mit zero explain oder einer lokalen Tabelle).
    • Wird ein repair angeboten und sieht sicher aus, zero fix --plan --json für die Edits aufrufen.
    • Die Edits anwenden (oder simulieren).
  5. Zurück zu Schritt 2.

Vergleich das mit dem Arbeiten an einer Prosa-Meldung: Der Agent muss Englisch parsen, eine plausible Zeilennummer extrahieren, die Art des Fixes erraten und den genauen Einfüge- oder Ersetzungstext inferieren. Jeder Schritt ist unscharf. Der JSON-Pfad ersetzt jeden Schritt durch einen Lookup gegen ein dokumentiertes Schema.

Jenseits von Fehlern: Graph und Size

--json ist nicht nur für Diagnostik. Andere Befehle stellen auf die gleiche Weise strukturierte Daten bereit:

  • zero graph --json – gibt den Abhängigkeitsgraphen eines Pakets als strukturierte Daten aus. Nützlich, um zu verstehen, was wovon abhängt, und für Agenten, die über Aufrufstellen nachdenken wollen, bevor sie sie anfassen.
  • zero size --json – meldet die On-Disk-Größe kompilierter Artefakte, aufgeschlüsselt nach Target. Dieselben Daten, die Menschen in zero size sehen, nur parsbar.

Diese Formen sind Teil des Designs: Wann immer der Compiler nützliche Daten hat, sind sie als JSON für Tools verfügbar, ohne Screen-Scraping.

Wie das Schema aussieht

Feldnamen und genaue Formen sind im Zero-Repository dokumentiert und entwickeln sich weiter, solange das Projekt pre-1.0 ist. Die Kategorien, die du erwarten kannst:

  • Lauf-Metadatenok, version, Timing.
  • Diagnostikcode, message, Ort (Datei/Zeile/Spalte/Byte-Bereiche), Schweregrad (error/warning/note), optional repair.
  • Repair-Pläne – wenn abgerufen, die strukturierte Edit-Liste.

Wenn du Tooling gegen diese Oberfläche baust, ist das sichere Muster: die Felder lesen, die du kennst, unbekannte Felder freundlich ignorieren und für Verhaltensentscheidungen auf code aufsetzen.

Ein schnelles End-to-End-Durchspiel

Nehmen wir an, dein Quellcode verwendet einen Bezeichner, der nirgends deklariert ist:

pub fun main(world: World) -> Void raises {
    check world.out.write(answer())   // 'answer' ist nirgends definiert
}

zero check --json erzeugt so etwas:

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

zero fix --plan --json liefert den Edit zurück:

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

zero fix (ohne --plan) wendet den Edit in-place an, danach liefert zero check ok: true. Jeder Schritt ist eine diskrete, inspizierbare Transaktion.

Warum das auch jenseits von Agenten zählt

Dieselben Eigenschaften – strukturierte Ausgabe, stabile Codes, Repair-Pläne – erleichtern auch:

  • Editoren und IDEs. Schlangenlinien und Glühbirnen, die auf repair-IDs reagieren statt auf geparsten Text.
  • CI-Pipelines. Fehlschläge, die mit code geloggt werden, für leichtes Grepping und Dashboarding.
  • Code-Mod-Tools. Massen-Fixes, die einen Code anvisieren, nicht einen Regex über Meldungen.

Das System wurde mit Agenten im Hinterkopf entworfen, aber menschen-orientiertes Tooling bekommt dieselben Vorteile.

Als Nächstes: Agent-First Design

Das Diagnostik-System ist das konkreteste Beispiel für Zeros Agent-first-Philosophie. Das nächste Dokument, Agent-first Design, zoomt zurück auf die zugrunde liegenden Prinzipien – kleine Oberfläche, deterministisches Tooling, explizite Effekte – und wie jedes davon seinen Platz verdient.

Häufig gestellte Fragen

Was ist JSON-Diagnostik in Zero?

Wenn du zero check --json (oder andere Befehle mit --json) ausführst, gibt der Compiler seine Befunde als strukturiertes JSON statt menschenformatierter Prosa aus. Jede Diagnostik trägt einen stabilen Fehlercode wie NAM003, die Quellposition, eine menschenlesbare Meldung und – wenn zutreffend – ein strukturiertes repair-Feld, das beschreibt, wie der Fehler zu beheben ist.

Warum gibt Zero JSON statt Klartext aus?

Agenten müssen Compiler-Ausgaben parsen. Klartext-Diagnostik ist für Menschen geschrieben und erfordert Regex über englische Sätze, um eine Zeilennummer zu extrahieren oder einen Fix zu erraten. JSON ist eindeutig: ein Agent liest das code-Feld, schlägt die dokumentierte Bedeutung nach und reagiert auf den strukturierten repair-Plan, ohne je Prosa zu parsen.

Was ist ein stabiler Fehlercode in Zero?

Jede Diagnostik, die der Compiler ausgeben kann, hat einen kurzen, stabilen Identifier wie NAM003 (unknown identifier). Der Vertrag ist, dass der Code seine Bedeutung über Compiler-Versionen hinweg behält, auch wenn die Formulierung der menschlichen Meldung sich ändert. Agenten und Tooling können auf den Code pattern-matchen, ohne sich um Drift der Meldung zu sorgen.

Was ist ein Repair-Plan?

Wenn der Compiler glaubt zu wissen, wie eine Diagnostik zu fixen ist, hängt er ein strukturiertes repair-Feld an, das die Art des Fixes nennt, den er vorschlagen würde. zero fix --plan --json aufzurufen liefert den vollständigen Plan – die anzuwendenden Edit-Operationen, die betroffenen Dateien und Bereiche. Ein Agent kann den Plan programmatisch anwenden, modifizieren oder verwerfen.

Wie hängt zero explain mit JSON-Diagnostik zusammen?

zero explain <code> liefert die menschenlesbare Erklärung für einen Diagnose-Code – was der Fehler bedeutet, warum der Compiler ihn wirft und wie typische Fixes aussehen. Das ist die Prosa-Seite der Diagnostik. Der Code ist stabil, sodass zwischengespeicherte Erklärungen gültig bleiben; Agenten holen sie, wenn ein Code außerhalb ihrer Trainingsdaten liegt.

Coddy programming languages illustration

Lerne mit Coddy zu programmieren

LOS GEHT'S