TANGEUL — Rules Written in Markdown, Audited by Humans Bild: KI-generiert

toulmin berechnet Verträge. Regeln sind Go-Funktionen, Ausnahmen werden als Widerlegungsgraph deklariert, und ein h-Categoriser verwandelt den Graphen in ein Urteil. Das Problem ist, dass die Person, die den Vertrag tatsächlich prüfen muss, meist kein Go lesen kann.

Ein Steuerberater, der eine Kreditrichtlinie prüft. Ein Kleinunternehmer, der eine Zugriffskontrollregel kontrolliert. Ein Bankangestellter, der die Kompensationslogik einer Überweisung überprüft. Keiner von ihnen kann auf func(ctx Context, specs Specs) (bool, any) schauen und sagen: „Ja, das ist korrekt." Egal wie fundiert die Mathematik der Engine ist — wenn der Leser den Code nicht lesen kann, ist die Prüfung nur Theater.

KI schreibt sie, ein Mensch liest sie

TANGL (Toulmin Amgoud Nute Graph Language) schließt diese Lücke. Man schreibt Markdown-Sätze, und diese Sätze sind der ausführbare Code.

## tangl:Cases
- in case of `can access`
  - `user` is required
  - `authenticate` is a general rule
  - `block ip` is a counter rule using `policy`.`IsIPBlocked` with `blocklist`
  - don't `authenticate` when `block ip`
  - do `policy`.`Allow` when `authenticate`

Diese fünf Zeilen sind der gesamte toulmin-Graph — Rule, Counter, Attacks und die Ausführungskante. Es gibt keinen separaten Kompilierungsschritt, an den der Autor denken müsste: die tangl-Toolchain parst dieses Markdown direkt in *ast.Document, und validate/effects/gen laufen unverändert darauf. Der Autor ist eine KI, der Prüfer ist ein Mensch — diese Asymmetrie ist der ganze Kern. Die KI muss nur eine strikte kanonische Grammatik befolgen; der Mensch muss nur einen Satz in seiner eigenen Sprache lesen.

Eine Semantik, viele Oberflächen

TANGLs Semantik wird einmal definiert, in der englischen Grammatik: Evaluate/Run-Dualität, once (Tick-Idempotenz), undo (Kompensation), Kaskaden-Timing, deterministische Ausführungsreihenfolge. Keine Sprachausgabe — Koreanisch oder welche auch immer als Nächstes kommt — definiert irgendetwas davon neu. Sie tauscht lediglich die Schlüsselwort- und Wortstellungstabelle aus, die auf demselben AST sitzt. Ein koreanischer Satz bildet 1:1 auf einen englischen Satz ab, und beide parsen zum identischen AST-Knoten.

Das ist keine der Bequemlichkeit halber aufgesetzte Übersetzungsschicht — es ist tragend. TANGLs eigentliche Leser in Korea sind Nicht-Entwickler als Prüfer: 소상공인, 세무사. Englische Schlüsselwörter wie don't X when Y oder is a general rule erlauben es einem Nicht-Entwickler nicht zu bestätigen: „Ja, das liest sich korrekt." Wenn der Leser Koreaner ist, muss die Oberfläche Koreanisch sein, damit die Prüfung tatsächlich funktioniert — und umgekehrt gilt symmetrisch dasselbe für englische Leser.

Der Bau der koreanischen Ausgabe brachte etwas zutage, das aus der englischen Grammatik allein nicht offensichtlich war: Koreanischs SOV-Reihenfolge ist keine Übersetzungslast, sondern ein besserer Sitz für bedingte Regeln. `Y`면 `X` 실행한다 (etwa „wenn Y, dann X ausführen") liest sich im Koreanischen natürlicher als do X when Y — Bedingung zuerst, Prädikat zuletzt ist schlicht die Art, wie die Sprache von Grund auf strukturiert ist. Die koreanische Partikelpolitik treibt dies weiter: Partikel (은/는/이/가/을/를 …) sind optionale Token, die der Lexer verwirft, doch die von der KI geschriebene kanonische Form enthält sie trotzdem stets — für den menschlichen Leser, nicht für den Parser. Da die KI der einzige Autor ist, muss der Parser niemals freie Wortstellung oder gesprochene Varianten akzeptieren; er muss nur eine kanonische Form parsen. Genau diese Asymmetrie macht eine nicht-triviale natürlichsprachliche Oberfläche überhaupt handhabbar.

Sieben Abschnitte

Subject → See → Definitions → Rules → Cases → Provides → Internal
AbschnittRolleErforderlich
Subjectdeklariert, worum das Dokument gehterforderlich
Seeverweist auf externe Paketsymboleoptional
DefinitionsBegriffe und Structsoptional
RulesInline-Bedingungsprädikateoptional
CasesUrteil + Ausführung (der Graph selbst)erforderlich
ProvidesEndpunkteoptional
Internaltick-/ereignisgesteuerte interne Arbeitoptional

Jedes Konstrukt ist nur in seinem eigenen Abschnitt gültig — dieselbe Scoping-Disziplin, die jede Sprachausgabe unverändert erbt. Anweisungen lesen sich als vollständige Sätze, die ihre eigene Art benennen: is a general rule, don't ... when, do ... once when, undo ... when, run ... when.

Beispiel: ein Kaffeeroboter

So zeigen sich TANGLs Ausführungssemantik — die Evaluate/Run-Dualität, once, Kaskadierung — als gewöhnliche Markdown-Sätze.

## tangl:Cases
- in case of `can place cup`
  - `order received` is a general rule using `sensor`.`isOrdered`
  - `no cup` is a counter rule using `sensor`.`noCupAvailable`
  - don't `order received` when `no cup`
  - do `arm`.`placeCup` once when `order received`
  - run `can pour water` when `order received`

- in case of `can pour water`
  - `cup placed` is a general rule using `sensor`.`cupIsPlaced`
  - do `arm`.`pourWater` once when `cup placed`
  - run `can brew espresso` when `cup placed`

## tangl:Provides
- provides `make coffee`
  - run `can place cup`

## tangl:Internal
- every 1s until `can serve coffee`
  - run `can place cup`

Ein Prüfer liest dies als: „Sobald der Becher platziert werden kann — wenn die Bestellung eingegangen ist, platziere den Becher einmal und gehe weiter zum Wassereingießen. Wenn kein Becher da ist, ist die Bestellung ungültig. Um Kaffee zu machen, beginne mit dem Platzieren des Bechers, und versuche es jede Sekunde erneut, bis er serviert werden kann."

Ohne once würde der Arm bei jedem Tick einen neuen Becher platzieren, solange die Bestellung aktiv bleibt — das Wort ist der ganze Grund, warum eine langsame Sensoraktualisierung nicht zu einem physisch unsicheren Neulauf wird. Ein Prüfer bestätigt die Neulauf-Sicherheit aus diesem einen Satz, ohne je eine Go-Guard-Klausel zu lesen.

Beispiel: Kompensation — die Welt bleibt heil, selbst bei Fehlschlag

undo ist nicht dasselbe wie eine Ablehnung. Eine Ablehnung ist ein normaler Zweig des Graphen; undo ist Kompensation für eine Ausführung, die auf halbem Weg starb.

- do `bank`.`withdraw` once when `balance sufficient`
- undo `bank`.`refund` when `balance sufficient`
- run `can deposit` when `balance sufficient`

„Wenn der Kontostand ausreicht, hebe einmal ab; wenn irgendetwas weiter unten fehlschlägt, mache es per Rückerstattung rückgängig; und fahre fort mit der Einzahlung." Bei Fehlschlag ist die Reihenfolge deterministisch:

1. withdraw succeeds        → refund is armed on the compensation stack
2. deposit errors           → the Run aborts immediately
3. stack unwinds LIFO       → refund fires, the money comes back
4. the original error is reported — the transfer failed, and the world looks like it never happened

Wenn refund selbst fehlschlägt, stoppen die verbleibenden Kompensationen und die gesamte Transaktion eskaliert zu einem menschlichen Prüf-Gate (REVIEW) — das System entscheidet für sich selbst, dass eine halb ausgeführte Überweisung nichts ist, das man automatisch übertünchen sollte.

Wo Text aufhört, die Quelle der Wahrheit zu sein — TANGEUL

Alles oben ist TANGL: Markdown-Text, direkt geparst und ausgeführt. Doch dass Text die Ausführungseingabe ist, ist eine Bequemlichkeit, keine Notwendigkeit. In dem Moment, in dem eine Sprache zwei Oberflächen hat — Englisch und Koreanisch — taucht die Frage auf: „Welche ist kanonisch?" Im Moment lautet die Antwort „Englisch, per Konvention." Das ist eine Entscheidung, keine strukturelle Garantie.

TANGEUL beseitigt die Frage, und es wird bereits als die binäre einzige Quelle der Wahrheit pkg/tangeul für die tangl-Toolchain ausgeliefert. Das kanonische Ausführungsartefakt ist ein binärer Graph-Stream (.tangeul), auf dem check/ast/effects/gen allesamt direkt laufen; die englischen und koreanischen Markdown-Dateien sind Oberflächen-Codecs, die in denselben Graphen aufgenommen und aus ihm wieder herausgerendert werden.

 EN .md ──[EN codec]──┐                        ┌──[mode 1]── verbatim byte-identical round trip
                      ├──> .tangeul (SSOT) ────┤
 KO .md ──[KO codec]──┘                        └──[mode 2]── normalized EN/KO rendering
  • Modus 1 (wortgetreu): spielt die verfassten Bytes exakt ab, sodass die Dekodierausgabe byte-identisch zum originalen .md ist — geprüft durch den CLI-Round-Trip-Test.
  • Modus 2 (regeneriert): decode --locale en|ko rendert jede Anweisung erneut durch den Codec der Zielsprache und spielt Prosa-Spannen wortgetreu ab. Ein auf Koreanisch verfasstes Dokument kann für einen englischen Prüfer gerendert werden und umgekehrt.

Die Verfassungsoberfläche eines Dokuments ist auf eine einzige Sprache festgelegt (das Mischen englischer und koreanischer Abschnitte in einer Datei wird abgelehnt), doch der .tangeul-Stream selbst weiß nicht, welche Sprache ihn geschrieben hat. Er kann bei Bedarf in beide Sprachen gerendert werden — gerade weil das kanonische Artefakt ein Graph ist, kein Absatz.

Alles Wissen auf Bit-Ebene ist in zwei Paketen abgeschottet — word (16-Bit-Wörter, Frame-Header) und codebook (nur anfügbare Code-Werte) — sodass die darüber liegenden Schichten (Pakete, Stream, der Dokumentcontainer) stabil bleiben, egal wie sich die Kodierung entwickelt:

pkg/tangeul/
├── word/       // 16-bit words, frame headers — bit-level knowledge stops here
├── codebook/   // NodeType/PropCode/Control codes, append-only
├── packet/     // Node/Edge/Control/Text packets
├── stream/     // Doc ↔ .tangeul serialization
└── doc/        // Doc container + VerifyTiling + the surface Codec interface

VerifyTiling ist das Integritäts-Gate: die aufgezeichneten Blöcke müssen den Quelltext exakt kacheln, und es läuft bei jedem Laden und bei jeder Encoder-Ausgabe. Paritätstests behaupten, dass der aus einem .tangeul-Stream geladene AST gleich dem AST ist, den der Parser aus dem originalen .md erzeugt (bis auf Zeilennummern). Die Umstellung auf binär geht nicht darum, zu ändern, was der Code tut — der Graph, und damit die generierte Ausgabe, ist identisch; es geht darum, die Möglichkeit von Drift zwischen mehreren Kopien desselben Textes strukturell zu beseitigen.

Prüfbare Verträge

toulmins Schlussfolgerung war, dass ein Urteil durch eine Formel berechnet und nicht von einer Person entschieden wird. TANGL fügt dem eine weitere Zeile hinzu: die Berechnung ist lesbar für jemanden, der die Formel nie geschrieben hat.

  • Warrant (eine Regel) = ein Satz, `n` is a ... rule
  • Rebuttal = ein Satz, don't `X` when `Y`
  • Ground (Evidenz) = ein Aufruf einer referenzierten Paketfunktion
  • Verdict = die h-Categoriser-Formel

Und TANGEUL ist die Arbeit, auf Byte-Ebene zu garantieren, dass diese Sätze auf denselben Graphen zeigen, egal in welcher Sprache sie geschrieben sind. Die Person, die die Regel schreibt, und die Person, die sie prüft, müssen keine Sprache mehr teilen.

MIT License. github.com/park-jun-woo/toulminpkg/tangl, pkg/tangeul, cmd/tangl.

Quellen

Änderungsverlauf

  • 2026-07-03: Erste Ausgabe