04 / 06

Agentes

Un asistente que escribe Nyx tiene un problema concreto: no sabe qué existe ya, y no sabe qué trampas tiene este lenguaje. Librado a sí mismo reinventa una función de la biblioteca estándar, o inventa sintaxis que parece correcta, o se mete en el código del compilador «para entender cómo funciona» y se pierde. Por eso nyx init siembra la respuesta a las dos preguntas dentro del proyecto, en archivos comunes que cualquier asistente puede leer.

Qué se siembra, y para qué sirve cada archivo

AGENTS.mdEl manual de campo: cómo se construye un programa acá, el procedimiento de decisión, los rieles duros y las trampas que arruinan un primer intento. Neutral respecto del proveedor, según la convención agents.md, así que cualquier asistente lee el mismo archivo.
CAPABILITIES.mdUn índice generado de la biblioteca estándar — lo que ya existe, para que nadie lo reescriba. Se regenera desde la toolchain instalada en cada nyx build, así que no puede quedar viejo.
docs/nyx/LLM.mdLa referencia densa: builtins, métodos, tipos, las trampas en su forma larga, patrones idiomáticos.
docs/nyx/guides/Tres guías — escribir un programa, arreglar un error de compilación y reportar fricción.

Nada de esto menciona a un asistente en particular. Es a propósito: el contexto es del proyecto, no de quien lo abra.

La regla que más tiempo ahorra

Lo primero que dice AGENTS.md, textual:

> **REGLA DE ORO — NO leas el fuente del compilador ni de la biblioteca estándar**
> (`std/`, `compiler/`, ni nada bajo tu instalación de Nyx) «para entender cómo funciona».
> No hace falta y te vas a perder. Si buscas una función, búscala en `CAPABILITIES.md`.
> Si buscas un modismo, búscalo en <https://nyxlang.com/by-example/>. **¿Sin acceso a
> internet?** `CAPABILITIES.md` alcanza para encontrar la función correcta — saltea la
> búsqueda del modismo y escribe el código directamente. Eso es todo.

El resto del archivo es un procedimiento de nueve pasos — enuncia la tarea, revisa CAPABILITIES.md, busca el modismo, escribe la cosa más chica que funcione, auto-verifica con nyx check y nyx vet, ejecútalo, pruébalo, lee el error si no compila, y detente si chocas contra una pared de verdad — seguido de cinco rieles duros: no inventes sintaxis, no reinventes la biblioteca estándar, no te metas en el fuente del compilador, no parches una limitación, no salgas del directorio del proyecto.

vet nombra la trampa en vez de dejar un error del parser

Algunos errores son grep-ables: tienen forma. nyx vet matchea esas formas y reporta cada una con un código estable, el archivo y la línea, así el asistente recibe la trampa por su nombre en vez de un error confuso tres pasos más adelante:

$ nyx vet shapes.nx
warning[W101] shapes.nx:2: Enum variants use `.`, not `::`: `Shape.Circle(5)`, never `Shape::Circle(5)`. (docs/nyx/LLM.md §5 enum-dot-not-colons)
warning[W102] shapes.nx:3: Map literal keys must be STRINGS: `{"k": 1}` and `{}` work (v0.16), but `{ident: 1}` is NOT a map literal and fails loudly with `NYX0106`. (docs/nyx/LLM.md §5 map-literal-string-keys)
warning[W104] shapes.nx:4: Channels must be Map, not int: `let ch: Map = channel_new(10)`, never `let ch: int`. (docs/nyx/LLM.md §5 channel-is-map)
warning[W103] shapes.nx:5: `charAt()` returns int (ASCII/codepoint), NOT String — compare with numbers: `if c == 65`. (docs/nyx/LLM.md §5 charat-returns-int)
warning[W107] shapes.nx:6: Check the return of `http_serve`/`tcp_listen`/`udp_bind`: a failed bind (port taken) returns `-1` — `if http_serve(8080, handler) < 0 { return 1 }`. (docs/nyx/LLM.md §5 check-bind-return)

Esos cinco son los códigos que existen hoy. La cola de cada línea — (docs/nyx/LLM.md §5 enum-dot-not-colons) — apunta a la entrada que lo explica largo, dentro del proyecto. El aviso y esa entrada no pueden decir cosas distintas: los dos se generan de la misma tabla.

Adaptadores, si tu herramienta quiere su propio archivo

$ nyx init my-app --agent=claude,cursor,copilot

Eso siembra, encima del andamiaje neutral, un archivo chico por cada herramienta nombrada, en el lugar donde cada una lo busca. Cada uno es un archivo corto que dice lo mismo: lee AGENTS.md primero, las guías están en docs/nyx/guides/, el índice de la biblioteca estándar es CAPABILITIES.md. Son punteros, no una segunda copia — hay exactamente una fuente de verdad, y duplicarla es la forma en que las dos versiones empiezan a contradecirse.

La bandera es además el único lugar de este sitio donde aparecen esos nombres. Al andamiaje le da igual qué asistente lo lea.

Primero la especificación, cuando el proyecto lo amerita

Para cualquier cosa más grande que un script, la falla cara no es el código malo — es el código que resuelve con confianza el problema equivocado. nyx init my-app --sdd (o nyx sdd init sobre un proyecto que ya tienes) siembra siete piezas que hacen que un asistente pregunte en vez de suponer:

docs/constitution.md          para qué existe el proyecto, y cómo se deciden las cosas
docs/glossary.md              las palabras que usa este proyecto, definidas una vez
docs/adr/0000-template.md     la plantilla de una decisión que sobrevive a una feature
docs/sdd/onboarding.md        cómo completar la constitución: 7 preguntas, de a una
specs/README.md               el ciclo, y la plantilla de spec
docs/evidence/nyx-0.31.0.md   generado: las trampas vivas en esta toolchain
tests/constitution_test.nx    generado: greppea src/ buscando lo que el compilador no ve

La constitución llega vacía, y lo dice:

**SDD_INCOMPLETE** — esta constitución todavía está vacía. Un agente que lee este marcador
**ofrece** al usuario completarla (`docs/sdd/onboarding.md`: una pregunta por sección, en
orden) y borra este párrafo SOLO cuando las siete secciones de abajo tienen al menos una
línea VERDADERA cada una. Nadie inventa contenido para sacarse el marcador de encima —
tres líneas verdaderas valen más que doce plausibles.

Ese marcador es todo el mecanismo. Un asistente que lo lee ofrece siete preguntas — propósito, usuarios, alcance y no-objetivos, invariantes, definición de terminado, restricciones técnicas, cómo se decide — de a una, anota las respuestas con las palabras del usuario, y borra el marcador solo cuando cada sección tiene una línea verdadera. «No aplica» es una respuesta válida; un valor por defecto plausible no lo es. Rechazar también está bien: --sdd es un ofrecimiento, y todo el andamiaje se revierte borrando los archivos que creó.

De ahí en adelante el ciclo es constitución primero, después specs/NNN-feature/spec.md (qué y por qué, con todo lo que no se puede contestar listado en Open questions en vez de adivinado), después plan.md (cómo), después tasks.md (cortado lo bastante chico como para verificar de a una). Una spec que contradice a la constitución está mal ella, no la constitución.

Dos de esas siete piezas se generan en vez de escribirse, y ese es el punto: docs/evidence/ lista las trampas que están vivas de verdad en la toolchain que sembró el proyecto, con el test que prueba cada una — si un manual la contradice, el manual está viejo. tests/constitution_test.nx convierte esa misma tabla en una prueba que greppea tu propio src/. Las dos las regenera nyx update, así que ninguna puede quedar describiendo en silencio una versión anterior.

Cuando genuinamente no se puede

$ nyx report

El paso nueve del procedimiento es detenerse. Si el lenguaje o la biblioteca estándar genuinamente no pueden hacer algo, o hay un bug, o los documentos estaban equivocados, nyx report crea un FRICTION.md en el proyecto con las secciones para completar: qué intentabas hacer, el código más chico que lo reproduce, y el error literal. No se envía nada a ningún lado — el archivo es local, el usuario lo lee, y mandárselo a quienes mantienen el lenguaje es un --send aparte y explícito. Un reporte limpio vale más que un parche.

Mantenerlo al día

Cada archivo sembrado termina con un sello que nombra la versión y el idioma que lo produjeron. Cuando la toolchain se adelanta a un proyecto, el wrapper nota la diferencia y avisa — una vez, por la salida de error, sin tocar el archivo, porque bien puede tener ediciones tuyas. Refrescarlo es decisión tuya:

$ nyx update --sync-docs

Corrido dentro del proyecto, resiembra AGENTS.md, la referencia y las guías desde la toolchain instalada, regenera CAPABILITIES.md, y deja un .bak de todo lo que difería. Los adaptadores por herramienta nunca se pisan: son opcionales y suelen estar editados.