Ir al contenido

El detector

El formato de AI-FIRST.md

AI-FIRST.md es el contrato entre el proyecto y el detector: dice qué gobierna al proyecto y dónde vive cada cosa, en una forma que audit puede verificar sin interpretar prosa. Vive en la raíz del repo, lo escribe init y lo mantiene el equipo a mano.

AGENTS.md es para los agentes. AI-FIRST.md es para las herramientas. El primero es normativo y está en presente: «no toques migrations/». El segundo es declarativo y no da órdenes: «migrations/ es Zona Prohibida desde el 2026-03-12, por esta razón». No lo lee el agente para trabajar; lo lee el detector para medir. La única skill que lo lee al empezar es protocolo-arranque, que toma de ahí el perfil, la fase, el comando de verificación y las Zonas Prohibidas.

Markdown con un frontmatter YAML entre dos líneas ---. El frontmatter es el contrato: lo lee el detector sin ambigüedad. El cuerpo es para humanos y el detector no lo interpreta: van ahí las notas que ninguna máquina puede verificar, como por qué cada zona es prohibida, o la tabla de permisos del repositorio. El cuerpo no repite el frontmatter: si un dato está en los dos lados, uno de los dos va a mentir.

Una clave que el detector no conoce se ignora, no es error.

Campo Tipo Obligatorio Lo escribe init Quién lo lee
formato número Sí Sí audit, antes que nada
proyecto cadena No Sí El reporte de audit
fase cadena No Sí Quien abre el archivo; protocolo-arranque
actualizado fecha No Sí Quien abre el archivo
verificacion cadena No Si lo deduce; si no, comentado El humano; protocolo-arranque
perfil mapa No Sólo con entrevista protocolo-arranque
zonas_prohibidas lista No Sí Verificación 1; protocolo-arranque
superficies_de_decision lista de cadenas No Si encuentra alguna; si no, comentado Verificación 2
alcance mapa No Sí, con spec Verificación 3
artefactos mapa No Sí Verificaciones 2, 3, 4 y 5
auditoria mapa No No: lo escribe audit --registrar El humano, en el diff del PR

Sin un campo opcional, la verificación que lo necesita se omite y el reporte dice por qué. Nunca se aprueba.

La versión del formato de este archivo, no del proyecto. Hoy la única que existe es 1. Cualquier otro valor, o su ausencia, detiene audit con un mensaje y sale con 2: un formato desconocido no se interpreta a medias.

formato: 1

El nombre que encabeza el reporte y el campo proyecto del JSON. Sin él, el reporte dice (sin nombre) y el JSON, null. init lo toma del name de package.json, sin el scope, o del nombre de la carpeta.

exploracion, mvp o produccion. No cambia ninguna verificación: la lee quien abre el archivo, y protocolo-arranque para saber en qué punto está el proyecto. init escribe exploracion salvo que la entrevista diga otra cosa.

La fecha de la última revisión del archivo, en formato AAAA-MM-DD. init pone la del día. Ninguna verificación la lee.

El comando que decide si el proyecto está sano, como pnpm build && pnpm test. Lo corre el humano, no el detector: audit mide documentación, no compila nada. init lo arma con los scripts build y test de package.json; si no los hay, deja la línea comentada.

Qué clase de producto es y en qué forma de repositorio vive. Decide qué skills instala init con entrevista y qué artefactos escribe protocolo-arranque.

perfil:
producto: saas # saas | landing | api | cli | movil
repositorio: unico # unico | monorepo | multiple

Las dos claves son obligatorias si el campo está. Un valor fuera de la lista es error de formato y sale con 2, no se reemplaza por uno por defecto: adivinar mal el perfil es peor que no tenerlo. Sin perfil, el archivo funciona igual; protocolo-arranque lo pregunta.

Las rutas que el agente no modifica sin aprobación explícita. El criterio es el costo de revertir un error ahí, no la importancia del archivo. Pocas, o se vuelven ruido.

zonas_prohibidas:
- ruta: "migrations/"
razon: "esquema vivo en producción"
desde: 2026-03-12
- ".env*"
Clave Tipo Obligatoria Qué es
ruta patrón Sí Qué se protege. Ver Patrones de ruta.
razon cadena No Por qué. Aparece en el mensaje del hallazgo.
desde fecha No Desde cuándo rige.

Cada entrada puede ser un mapa o, si sólo lleva ruta, una cadena suelta. Un mapa sin ruta es error de formato.

Los archivos donde un cambio se presume decisión arquitectónica: el esquema, los puntos de entrada de los paquetes, las configuraciones. Si uno se toca y el ADR no gana una fila, la verificación 2 emite un P1. Las dependencias de producción se vigilan solas, sin declararlas.

superficies_de_decision:
- "**/*.config.*"
- "packages/*/src/index.ts"
- "src/lib/queue.ts"

Tiene que ser una lista de cadenas.

De dónde sale el alcance declarado del cambio en curso.

alcance:
spec: docs/changes/pending/
tolerancia: 3
Clave Tipo Por defecto Qué es
spec ruta — Un archivo, o una carpeta cuyos .md y .mdx son las specs activas. Sin ella, la verificación 3 se omite.
tolerancia número 0 Cuántos archivos fuera del alcance se aceptan antes de emitir el P1.

Cómo lista archivos una spec está en Alcance excedido. Un valor del tipo equivocado, como tolerancia: "3" entre comillas, se ignora sin error.

Los documentos que hablan de este repo, como un mapa de nombre a ruta relativa a la raíz. La verificación 4 comprueba que existan y que lo que mencionan exista; la 3 nunca los cuenta fuera de alcance.

artefactos:
adr: docs/ADR.md
agents: AGENTS.md
arquitectura: docs/ARQUITECTURA.md
guia_diseno: docs/GUIA_DISENO.md
inventario_componentes: docs/COMPONENTES.md
componentes_dir: src/components/
tech_notes: docs/TECH_NOTES.md
Clave La usa además
adr Verificación 2: es el archivo que tiene que ganar la fila.
inventario_componentes Verificación 5, junto con componentes_dir.
componentes_dir Verificación 5. Es una carpeta: sólo tiene que existir.
agents, arquitectura, guia_diseno, tech_notes, session_log, change_log Sólo la 4.

Se admite cualquier otra clave: es un documento más que la verificación 4 recorre. Cada valor tiene que ser una cadena con la ruta; una clave con valor nulo se ignora.

El resultado de la última corrida registrada. Lo escribe audit --registrar y nadie más; ninguna verificación lo lee. Existe para que el diff del PR muestre si la entropía subió o bajó.

auditoria:
fecha: 2026-09-23
entropia: 40
hallazgos:
p0: 1
p1: 0
p2: 0

Cómo se escribe está en --registrar.

zonas_prohibidas, superficies_de_decision y las rutas que declara una spec usan las mismas reglas, pocas y explícitas:

Forma Ejemplo Coincide con
Termina en / migrations/ Todo lo que esté debajo de esa carpeta, a cualquier profundidad, desde la raíz.
Sin / .env* El nombre del archivo, en cualquier carpeta: también apps/web/.env.local.
Con / packages/*/src/index.ts La ruta completa desde la raíz.

Dentro de un patrón, * y ? no cruzan carpetas; ** sí, y puede valer cero carpetas. Las rutas son relativas a la raíz y se escriben con /, que es como las entrega git.

Cualquiera de estos detiene audit y sale con 2, con el mensaje en la salida de error:

Mensaje Causa
No hay AI-FIRST.md en … El archivo no existe en la raíz.
AI-FIRST.md no tiene frontmatter YAML entre dos líneas «---». Falta el frontmatter, o no está al principio.
El frontmatter no es un mapa YAML. El YAML es una lista o un valor suelto.
«formato: …» no está soportado. Este detector entiende el formato 1. formato falta o no es 1.
«zonas_prohibidas» debe ser una lista. —
«zonas_prohibidas[n]» necesita al menos «ruta». Una entrada es un mapa sin ruta.
«superficies_de_decision» debe ser una lista de cadenas. —
«alcance» debe ser un mapa. —
«artefactos» debe ser un mapa de nombre → ruta. —
«artefactos.clave» debe ser una ruta. Un valor no es cadena.
«perfil.producto» debe ser uno de: saas, landing, api, cli, movil. También su equivalente para repositorio.

El AI-FIRST.md que deja init --sin-entrevista en una carpeta vacía llamada demo:

---
# Versión del FORMATO de este archivo, no del proyecto.
formato: 1
proyecto: "demo"
fase: exploracion # exploracion | mvp | produccion
actualizado: 2026-09-23
# El comando que decide si el proyecto está sano. Lo corre el humano, no el
# detector: audit mide documentación, no compila nada.
# verificacion: pnpm build && pnpm test
# Rutas que el agente no modifica sin aprobación explícita. El criterio es el
# costo de revertir un error ahí, no la importancia del archivo. Pocas, o se
# vuelven ruido. Revisa las sugeridas y completa la razón.
zonas_prohibidas:
- ruta: ".env*"
razon: "credenciales"
desde: 2026-09-23
# Superficies donde un cambio se presume decisión arquitectónica. Si una se toca
# y el ADR no gana una fila, audit emite P1. Las dependencias de producción se
# vigilan solas, sin declararlas.
# superficies_de_decision:
# - "**/*.config.*"
# - src/lib/queue.ts
# Alcance de la sesión en curso: la spec del cambio abierto (CHG-XXX), que vive
# en la carpeta que init acaba de crear. Requiere que la spec liste archivos en
# una sección «Archivos» o «Alcance», con rutas entre acentos graves. Sin spec
# activa el check se omite, que es lo correcto: no hay alcance que exceder.
alcance:
spec: docs/changes/pending/
# tolerancia: 3
# Documentos que hablan de ESTE repo. audit verifica que lo que mencionan
# exista. Un check sin su artefacto se omite, nunca se aprueba.
artefactos:
adr: "docs/ADR.md"
agents: "AGENTS.md"
---
# AI-FIRST.md — demo
> Qué gobierna a este proyecto. Las reglas que el agente obedece están en
> `AGENTS.md`; acá está el mapa que las herramientas verifican.
## Notas
Por qué `.env*` es Zona Prohibida: _(completar: qué cuesta revertir un error ahí)_.

Con entrevista, el archivo lleva además el bloque perfil y la fase y la verificacion que se respondieron. En un repo con componentes, init agrega bajo artefactos las dos claves de la verificación 5, comentadas, para que las actives tú.