Imagen: generada por IA
toulmin computa contratos. Las reglas son funciones Go, las excepciones se declaran como un grafo de derrotas y un h-Categoriser convierte el grafo en un veredicto. El problema es que la persona que realmente necesita auditar el contrato normalmente no sabe leer Go.
Un asesor fiscal auditando una política de préstamos. Un pequeño empresario revisando una regla de control de acceso. Un cajero de banco revisando la lógica de compensación de una transferencia. Ninguno de ellos puede mirar func(ctx Context, specs Specs) (bool, any) y decir “sí, esto es correcto.” Por muy sólida que sea la matemática del motor, si el lector no sabe leer el código, la auditoría es teatro.
La IA lo escribe, un humano lo lee
TANGL (Toulmin Amgoud Nute Graph Language) cierra esa brecha. Escribes frases en markdown, y esas frases son el código ejecutable.
## 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`
Estas cinco líneas son el grafo de toulmin completo — Rule, Counter, Attacks y la arista de ejecución. No hay un paso de compilación separado en el que el autor tenga que pensar: la cadena de herramientas tangl analiza este markdown directamente en *ast.Document, y validate/effects/gen se ejecutan sobre él sin cambios. El autor es una IA, el verificador es una persona — esa asimetría es todo el propósito. La IA solo tiene que seguir una gramática canónica estricta; el humano solo tiene que leer una frase en su propio idioma.
Una semántica, muchas superficies
La semántica de TANGL se define una sola vez, en la gramática inglesa: dualidad Evaluate/Run, once (idempotencia por tick), undo (compensación), temporización de cascada, orden de ejecución determinista. Cualquier edición de localización — coreano, o la que venga después — no redefine nada de esto. Solo intercambia la tabla de palabras clave y orden de palabras que se asienta sobre el mismo AST. Una frase coreana se corresponde 1:1 con una frase inglesa, y ambas se analizan hacia el nodo AST idéntico.
Eso no es una capa de traducción atornillada por conveniencia — es estructural. Los lectores reales de TANGL en Corea son auditores no desarrolladores: 소상공인, 세무사. Palabras clave inglesas como don't X when Y o is a general rule no permiten a un no desarrollador confirmar “sí, esto se lee correctamente.” Si el lector es coreano, la superficie tiene que ser coreana para que la auditoría funcione de verdad — y lo inverso se cumple simétricamente para los lectores ingleses.
Construir la edición coreana sacó a la luz algo no obvio a partir de la gramática inglesa por sí sola: el orden SOV del coreano no es una carga de traducción, es un mejor encaje para las reglas condicionales. `Y`면 `X` 실행한다 (aproximadamente, “cuando Y, haz X”) se lee de forma más natural que do X when Y en coreano — condición primero, predicado al final es simplemente cómo el idioma está estructurado desde el inicio. La política de partículas coreanas lleva esto más lejos: las partículas (은/는/이/가/을/를 …) son tokens opcionales que el lexer descarta, pero la forma canónica escrita por la IA siempre las incluye de todos modos — para el lector humano, no para el analizador. Como la IA es el único autor, el analizador nunca tiene que aceptar orden libre de palabras ni variación hablada; solo tiene que analizar una forma canónica. Esa asimetría es lo que hace que una superficie de lenguaje natural no trivial sea tratable siquiera.
Siete secciones
Subject → See → Definitions → Rules → Cases → Provides → Internal
| Sección | Rol | Requerida |
|---|---|---|
| Subject | declara de qué trata el documento | requerida |
| See | referencia símbolos de paquetes externos | opcional |
| Definitions | términos y structs | opcional |
| Rules | predicados de condición en línea | opcional |
| Cases | juicio + ejecución (el grafo en sí) | requerida |
| Provides | endpoints | opcional |
| Internal | trabajo interno guiado por tick/eventos | opcional |
Cada constructo solo es válido en su propia sección — la misma disciplina de alcance que cualquier edición de localización hereda sin cambios. Las sentencias se leen como frases completas que nombran su propia clase: is a general rule, don't ... when, do ... once when, undo ... when, run ... when.
Ejemplo: un robot de café
Así es como la semántica de ejecución de TANGL — la dualidad Evaluate/Run, once, la cascada — se manifiesta como frases ordinarias de markdown.
## 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`
Un auditor lo lee así: “Una vez que se puede colocar la taza — si el pedido fue recibido, coloca la taza una vez y pasa a verter el agua. Si no hay taza, el pedido queda anulado. Para hacer café, empieza colocando la taza, y reintenta cada segundo hasta que se pueda servir.”
Sin once, el brazo colocaría una taza nueva en cada tick durante todo el tiempo que el pedido siga activo — la palabra es toda la razón por la que una actualización lenta del sensor no se convierte en una re-ejecución físicamente insegura. Un auditor confirma la seguridad de re-ejecución a partir de esta única frase, sin leer nunca una cláusula de guarda en Go.
Ejemplo: compensación — el mundo permanece íntegro incluso ante el fallo
undo no es lo mismo que un rechazo. Un rechazo es una rama normal del grafo; undo es compensación para una ejecución que murió a mitad de camino.
- do `bank`.`withdraw` once when `balance sufficient`
- undo `bank`.`refund` when `balance sufficient`
- run `can deposit` when `balance sufficient`
“Si el saldo es suficiente, retira una vez; si algo aguas abajo falla, revierte mediante reembolso; y continúa hasta el depósito.” Ante el fallo, el orden es determinista:
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
Si refund falla en sí mismo, las compensaciones restantes se detienen y toda la transacción escala a una puerta de revisión humana (REVIEW) — el sistema decide por sí mismo que una transferencia ejecutada a medias no es algo que deba encubrirse automáticamente.
Donde el texto deja de ser la fuente de verdad — TANGEUL
Todo lo anterior es TANGL: texto en markdown analizado y ejecutado directamente. Pero que el texto sea la entrada de ejecución es una conveniencia, no una necesidad. En el momento en que un lenguaje tiene dos superficies — inglés y coreano — aparece la pregunta “¿cuál es la canónica?”. Ahora mismo la respuesta es “el inglés, por convención.” Eso es una decisión, no una garantía estructural.
TANGEUL elimina la pregunta, y ya se distribuye como la fuente de verdad única binaria pkg/tangeul para la cadena de herramientas tangl. El artefacto de ejecución canónico es un flujo de grafo binario (.tangeul) sobre el que check/ast/effects/gen se ejecutan directamente; los archivos markdown en inglés y coreano son códecs de superficie que se absorben en, y se renderizan de vuelta desde, ese mismo grafo.
EN .md ──[EN codec]──┐ ┌──[mode 1]── verbatim byte-identical round trip
├──> .tangeul (SSOT) ────┤
KO .md ──[KO codec]──┘ └──[mode 2]── normalized EN/KO rendering
- Modo 1 (verbatim): reproduce los bytes autorizados exactamente, de modo que la salida de decodificación es idéntica byte a byte al
.mdoriginal — verificado por la prueba de ida y vuelta de la CLI. - Modo 2 (regenerado):
decode --locale en|kovuelve a renderizar cada sentencia a través del códec de la localización de destino, reproduciendo los tramos de prosa verbatim. Un documento escrito en coreano puede renderizarse para un auditor inglés, y viceversa.
La superficie de autoría de un documento está fijada a una única localización (mezclar secciones en inglés y coreano en un mismo archivo se rechaza), pero el flujo .tangeul en sí no sabe qué localización lo escribió. Puede renderizarse en cualquiera de los dos idiomas bajo demanda precisamente porque el artefacto canónico es un grafo, no un párrafo.
Todo el conocimiento a nivel de bits está en cuarentena en dos paquetes — word (palabras de 16 bits, cabeceras de frame) y codebook (valores de código de solo adición) — de modo que las capas por encima de ellos (packets, stream, el contenedor de documento) permanecen estables sin importar cómo evolucione la codificación:
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 es la puerta de integridad: los bloques registrados deben teselar el texto fuente exactamente, y se ejecuta en cada carga y en cada salida del codificador. Las pruebas de paridad afirman que el AST cargado desde un flujo .tangeul es igual al AST que el analizador produce a partir del .md original (salvo los números de línea). Reorientar a binario no consiste en cambiar lo que hace el código — el grafo, y por tanto la salida generada, es idéntico; consiste en eliminar estructuralmente la posibilidad de deriva entre múltiples copias del mismo texto.
Contratos auditables
La conclusión de toulmin fue que un veredicto lo computa una fórmula, no lo decide una persona. TANGL añade una línea más a eso: la computación es legible por alguien que nunca escribió la fórmula.
- Warrant (una regla) = una frase,
`n` is a ... rule - Rebuttal = una frase,
don't `X` when `Y` - Ground (evidencia) = una llamada a una función de paquete referenciada
- Verdict = la fórmula del h-Categoriser
Y TANGEUL es el trabajo de garantizar, a nivel de bytes, que estas frases apuntan al mismo grafo independientemente del idioma en que estén escritas. La persona que escribe la regla y la persona que la audita ya no tienen que compartir un idioma.
MIT License. github.com/park-jun-woo/toulmin — pkg/tangl, pkg/tangeul, cmd/tangl.
Referencias
- TANGL — la gramática de markdown ejecutable (TANGEUL.en.md)
- pkg/tangeul — el formato SSOT binario (README)
- park-jun-woo/toulmin — el motor de reglas y la cadena de herramientas tangl
Registro de cambios
- 2026-07-03: Primera edición