# ai-first audit

> Los dos modos de audit, sus opciones, el puntaje de entropía, los códigos de salida y el formato del reporte legible y del JSON.

`audit` lee `AI-FIRST.md`, le pregunta a git qué cambió, corre las cinco verificaciones y resume el resultado en un puntaje de entropía y un código de salida. No compila nada, no llama a un modelo y no toca la red.

## Uso

```text
ai-first audit [--base <ref>] [--estricto] [--registrar] [--json] [--raiz <dir>]
```

Para correrlo sin instalar el paquete:

```bash
npx @falcux/ai-first@latest audit
```

## Modos

El mismo comando compara dos cosas distintas según reciba o no `--base`.

| Modo      | Se activa      | Qué cuenta como tocado                                                                                                                                           | Dónde se usa                                                                     |
| --------- | -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- |
| **Árbol** | Sin `--base`   | Lo que difiere de `HEAD`, en el índice o en el árbol de trabajo, más los archivos nuevos sin seguimiento que `.gitignore` no cubre. En un repo sin commits, todo | El hook local, o a mano antes de hacer commit                                    |
| **Rango** | `--base <ref>` | Lo que difiere en el rango `<ref>...HEAD`: lo que la rama trae desde que se separó de `<ref>`                                                                    | Integración continua, y el hook `pre-push` cuando la rama ya existe en el remoto |

La diferencia importa para una verificación: la anotación que silencia la de decisiones vive en el cuerpo de un commit, y en modo árbol no hay commits que leer. Ver [Decisión sin fila en ADR](https://ai-first.falcux.com/docs/referencia/verificaciones/#decisi%C3%B3n-sin-fila-en-adr).

## Opciones

| Opción         | Qué hace                                                                                        | Por defecto               |
| -------------- | ----------------------------------------------------------------------------------------------- | ------------------------- |
| `--base <ref>` | Compara el rango `<ref>...HEAD`. La ref tiene que existir en el repositorio; si no, sale con 2. | Modo árbol, contra `HEAD` |
| `--estricto`   | Sale con 1 también ante un P1 o un P2.                                                          | Sólo un P0 da 1           |
| `--registrar`  | Escribe el resultado en `auditoria` del frontmatter de `AI-FIRST.md`.                           | No escribe nada           |
| `--json`       | Imprime el informe en JSON en vez del reporte legible.                                          | Reporte legible           |
| `--raiz <dir>` | Raíz del repositorio.                                                                           | El directorio actual      |

## Opciones globales

Valen sin subcomando y con cualquiera de los dos.

| Opción            | Qué hace                                                                                                   | Código de salida |
| ----------------- | ---------------------------------------------------------------------------------------------------------- | ---------------- |
| `-v`, `--version` | Imprime la versión instalada del paquete, leída de su `package.json`. Tiene prioridad sobre todo lo demás. | `0`              |
| `-h`, `--help`    | Imprime la ayuda completa, la de `init` y la de `audit`.                                                   | `0`              |

Sin subcomando y sin `--help`, el binario imprime la misma ayuda pero sale con `2`, porque no se le pidió nada que hacer.

## Estados de una verificación

Cada una de las cinco termina en uno de tres estados, y sólo tres:

| Estado      | Marca en el reporte | Qué significa                                                      |
| ----------- | ------------------- | ------------------------------------------------------------------ |
| `aprobado`  | `✓`                 | Corrió y no encontró nada.                                         |
| `hallazgos` | `✗`                 | Corrió y encontró al menos un hallazgo, cada uno con su severidad. |
| `omitido`   | `–`                 | No pudo correr porque falta lo que necesita leer. Se dice por qué. |

**Un check que no puede correr se reporta omitido, nunca aprobado.** Un `–` no es un visto bueno: es un hueco en la configuración, y el reporte dice cuál. Qué necesita cada uno está en [Las cinco verificaciones](https://ai-first.falcux.com/docs/referencia/verificaciones/).

## Puntaje

```text
entropía = min(100, 40·P0 + 20·P1 + 8·P2)
```

**Más alto es peor.** Mide entropía, no salud: 0 es documentación alineada con el proyecto y 100 es documentación desconectada. Cada hallazgo suma el peso de su severidad, y el total se corta en 100.

Un solo P0 pone el puntaje en 40 sin ayuda de nada más, que es la intención: una Zona Prohibida tocada no se compensa con documentación impecable en todo lo demás. Un P0, un P1 y un P2 dan 68.

En la verificación de Zonas Prohibidas, la unidad del hallazgo es la zona, no el archivo: tocar tres migraciones es un P0, con los tres archivos en el detalle. El puntaje mide cuántas fronteras se cruzaron.

## Códigos de salida

| Código | Cuándo                                                                                                                                                                                                                                                                        |
| ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `0`    | Sin hallazgos, o sólo P1 y P2 sin `--estricto`.                                                                                                                                                                                                                               |
| `1`    | Algún P0. O algún P1 o P2 con `--estricto`.                                                                                                                                                                                                                                   |
| `2`    | Error de uso: no hay `AI-FIRST.md`, su `formato` es desconocido o su frontmatter no se puede leer, la carpeta no es un repositorio git, la ref de `--base` no existe, o una opción desconocida. También `sync`, `adr` y `handoff`, que están anunciados y todavía no existen. |

Así el mismo comando sirve en un hook local, donde interrumpir por un P2 sería intolerable, y en integración continua, donde se quiere el corte.

## Reporte legible

Es la salida por defecto. En una terminal lleva color; redirigida a un archivo o a otro proceso, no.

Sin hallazgos:

```text
ai-first audit — demo
árbol de trabajo contra HEAD · 0 archivos tocados


✓ Zona Prohibida tocada
✓ Decisión sin fila en ADR
– Alcance excedido — omitido: no hay ninguna spec activa en docs/changes/pending/
✓ Artefacto huérfano
– Inventario de componentes desactualizado — omitido: faltan «artefactos.inventario_componentes» o «artefactos.componentes_dir»


Entropía: 0 / 100 (0 P0 · 0 P1 · 0 P2)
```

Sale con 0. Tras tocar un `.env.local` en el mismo repo, que declara `.env*` como Zona Prohibida:

```text
ai-first audit — demo
árbol de trabajo contra HEAD · 2 archivos tocados


✗ Zona Prohibida tocada
    P0  Zona Prohibida «.env*» tocada — credenciales
          .env.local
✓ Decisión sin fila en ADR
– Alcance excedido — omitido: no hay ninguna spec activa en docs/changes/pending/
✓ Artefacto huérfano
– Inventario de componentes desactualizado — omitido: faltan «artefactos.inventario_componentes» o «artefactos.componentes_dir»


Entropía: 40 / 100 (1 P0 · 0 P1 · 0 P2)
```

Sale con 1. La segunda línea dice el modo —`árbol de trabajo contra HEAD`, o `rango <ref>...HEAD`— y cuántos archivos se tocaron. Las verificaciones van siempre en el mismo orden. Bajo cada hallazgo, con sangría, va su detalle: los archivos que lo causaron o qué hacer para silenciarlo.

## Salida JSON

Con `--json`, el mismo informe de la corrida con P0:

```json
{
  "proyecto": "demo",
  "modo": "arbol",
  "cambiados": [
    ".env.local",
    "src/a.ts"
  ],
  "resultados": [
    {
      "check": "zona-prohibida",
      "estado": "hallazgos",
      "hallazgos": [
        {
          "severidad": "P0",
          "ruta": ".env*",
          "mensaje": "Zona Prohibida «.env*» tocada — credenciales",
          "detalle": [
            ".env.local"
          ]
        }
      ]
    },
    {
      "check": "decision-sin-adr",
      "estado": "aprobado"
    },
    {
      "check": "alcance-excedido",
      "estado": "omitido",
      "razon": "no hay ninguna spec activa en docs/changes/pending/"
    },
    {
      "check": "artefacto-huerfano",
      "estado": "aprobado"
    },
    {
      "check": "inventario-componentes",
      "estado": "omitido",
      "razon": "faltan «artefactos.inventario_componentes» o «artefactos.componentes_dir»"
    }
  ],
  "conteo": {
    "p0": 1,
    "p1": 0,
    "p2": 0
  },
  "entropia": 40,
  "codigoDeSalida": 1
}
```

| Campo                    | Tipo                  | Qué contiene                                                                                                                                                                                                     |
| ------------------------ | --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `proyecto`               | cadena o `null`       | El `proyecto` de `AI-FIRST.md`, o `null` si no lo declara.                                                                                                                                                       |
| `modo`                   | `"arbol"` o `"rango"` | El modo de comparación.                                                                                                                                                                                          |
| `base`                   | cadena                | La ref de `--base`. Sólo aparece en modo rango.                                                                                                                                                                  |
| `cambiados`              | lista de cadenas      | Los archivos tocados, relativos a la raíz, sin duplicados y en orden alfabético.                                                                                                                                 |
| `resultados`             | lista                 | Uno por verificación, en el orden fijo del reporte.                                                                                                                                                              |
| `resultados[].check`     | cadena                | El identificador: `zona-prohibida`, `decision-sin-adr`, `alcance-excedido`, `artefacto-huerfano` o `inventario-componentes`.                                                                                     |
| `resultados[].estado`    | cadena                | `aprobado`, `hallazgos` u `omitido`.                                                                                                                                                                             |
| `resultados[].razon`     | cadena                | Por qué se omitió. Sólo con `omitido`.                                                                                                                                                                           |
| `resultados[].hallazgos` | lista                 | Sólo con `hallazgos`. Cada uno lleva `severidad` (`P0`, `P1` o `P2`), `mensaje` en una línea y, cuando aplica, `ruta` —el patrón, archivo o `archivo:línea` al que se refiere— y `detalle`, una lista de líneas. |
| `conteo`                 | objeto                | Cuántos hallazgos de cada severidad: `p0`, `p1`, `p2`.                                                                                                                                                           |
| `entropia`               | número                | El puntaje, de 0 a 100.                                                                                                                                                                                          |
| `codigoDeSalida`         | `0` o `1`             | El código con el que sale esta corrida, ya aplicado `--estricto`.                                                                                                                                                |

Nota

`codigoDeSalida` nunca vale `2`: un error de uso no produce informe, sino un mensaje en la salida de error que empieza con `ai-first:`.

## `--registrar`

Escribe en el frontmatter de `AI-FIRST.md` un bloque `auditoria` con la fecha de hoy, el puntaje y el conteo. Si el bloque ya existe, lo reemplaza; si no, lo agrega al final del frontmatter. Trabaja sobre el texto, no reformatea el YAML: los comentarios y el resto del archivo quedan como estaban.

Tras la corrida con P0, el frontmatter termina así:

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

Sólo guarda la última corrida, y sólo cuando se pide. Si cada `audit` tocara el archivo, el ruido en los diffs haría que el equipo lo ignore. Registrado en un PR, el diff muestra si la entropía subió o bajó. El registro no cambia el código de salida.

## Relacionado

[Las cinco verificaciones](https://ai-first.falcux.com/docs/referencia/verificaciones/)Qué detecta cada una y cómo se silencia.

[Auditar en local y en CI](https://ai-first.falcux.com/docs/guias/auditar-en-local-y-en-ci/)El hook, el flujo de integración continua y qué hacer con cada hallazgo.

[El formato de AI-FIRST.md](https://ai-first.falcux.com/docs/referencia/ai-first-md/)Lo que audit lee antes de correr.

[Solución de problemas](https://ai-first.falcux.com/docs/guias/solucion-de-problemas/)Cuando el comando sale con 2 o un check aparece omitido.
