Ir al contenido

Guías

Auditar en local y en CI

Tienes el proyecto inicializado y quieres que la entropía documental se mida sola, sin depender de que alguien se acuerde de correr audit. init deja escrito el punto de control: el mismo detector en dos sitios, con tolerancias distintas.

Dónde Cuándo corre Qué lo detiene
Hook de git .githooks/pre-push En cada git push, en tu máquina Sólo un P0
Flujo .github/workflows/ai-first.yml En cada pull request Cualquier hallazgo, con --estricto
  • Acabas de correr init y quieres entender qué dejó en el push y en los pull requests.
  • Tu CI no es GitHub Actions y necesitas el comando para montarlo.
  • Quieres leer el resultado desde otra herramienta, o guardarlo en AI-FIRST.md.

Si lo que quieres es evitar un hallazgo concreto, la guía del flujo que lo produce lo explica: Cambiar algo que ya funciona para el alcance, Cerrar la sesión para la fila del ADR.

init escribe los dos por defecto. --sin-hook y --sin-ci los omiten, y --hook-local deja el hook en .git/hooks/, que no viaja en el clon, en vez de .githooks/, que sí viaja y se revisa en un PR.

El hook no baja nada de la red: usa el detector del proyecto, el del PATH o el que npx ya tenga en su caché. Para que siempre lo encuentre, instálalo como dependencia de desarrollo:

Ventana de terminal
pnpm add -D @falcux/ai-first
  1. Corre el detector a mano una vez. Sin opciones, compara el árbol de trabajo contra HEAD:

    Ventana de terminal
    npx @falcux/ai-first@latest audit

    Un repo recién inicializado, sin cambios:

    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)

    Un check omitido no es un check aprobado: le falta lo que necesita para correr, y la razón lo dice.

  2. Mira qué hace el hook. init lo escribe en .githooks/pre-push y apunta core.hooksPath a esa carpeta. En cada push, toma como base lo que el remoto ya tiene y corre audit --base sobre ese rango; si la rama todavía no existe en el remoto, corre contra el árbol de trabajo. Corre sin --estricto: un P1 o un P2 se imprimen y el push sigue. Un P0 lo detiene. Así se ve uno, en el mismo repo después de tocar .env.local:

    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)

    Si no encuentra node o el detector, avisa y deja pasar el push: no encontrarse a sí mismo no es motivo para frenar a nadie.

  3. Sáltalo cuando haga falta. Si el push tiene que salir igual, lo decides tú:

    Ventana de terminal
    git push --no-verify

    El hook no lo combate. El detector informa; la disciplina es del equipo.

  4. Revisa el flujo de CI. Es el archivo que escribe init, tal cual:

    # El punto de control de la metodología AI-First, en integración continua.
    #
    # Lo escribe `ai-first init`. A diferencia del hook local, éste corre **con
    # `--estricto`**: acá el corte por P1 y P2 sí se quiere, porque hay un humano
    # revisando y el costo de parar es un rebote, no una interrupción.
    name: ai-first
    on:
    pull_request:
    jobs:
    auditar:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4
    with:
    # El detector compara contra la rama base: sin historia no hay rango.
    fetch-depth: 0
    - uses: actions/setup-node@v4
    with:
    node-version: 22
    - name: Entropía documental
    run: npx --yes @falcux/ai-first audit --base "origin/${{ github.base_ref }}" --estricto

    Tres cosas sostienen el paso. fetch-depth: 0 trae la historia: sin ella, la rama base no existe en el checkout y audit sale con código 2, avisando que la ref no existe en el repositorio. --base compara el rango de la rama base a HEAD, que es lo que el pull request agrega. --estricto hace que un P1 o un P2 también fallen el paso.

  5. Móntalo en otro CI, si no usas GitHub. El paso es el mismo comando, con Node 22.12 o superior, la historia completa del repo y la rama base del pull request o merge request:

    Ventana de terminal
    npx --yes @falcux/ai-first@latest audit --base "origin/<rama base>" --estricto
Código Cuándo
0 Sin hallazgos, o sólo P1 y P2 sin --estricto
1 Cualquier P0, o cualquier hallazgo con --estricto
2 Error de uso: no es un repo git, no hay AI-FIRST.md, la ref de --base no existe

Con --json, la misma información sale en JSON. Es la salida real del ejemplo del P0 de arriba:

{
"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
}

modo es arbol sin --base y rango con ella. El código de salida del proceso es el mismo que codigoDeSalida.

--registrar escribe el resultado en el bloque auditoria del frontmatter de AI-FIRST.md: la fecha, la entropía y el conteo de P0, P1 y P2. Sólo lo escribe cuando lo pides, y sólo reemplaza ese bloque, sin tocar el resto del frontmatter. Como cualquier cambio del repo, queda en la historia si lo commiteas.

Ventana de terminal
npx @falcux/ai-first@latest audit --registrar
Archivo Qué es
.githooks/pre-push El hook, ejecutable; con --hook-local, en .git/hooks/pre-push
core.hooksPath La configuración local de git que apunta a .githooks/
.github/workflows/ai-first.yml El flujo de GitHub Actions
El bloque auditoria de AI-FIRST.md Sólo con --registrar

Esta guía es el detector: los cinco checks corren en los dos sitios. Lo que cambia es qué detiene el trabajo. En el hook, sólo Zona Prohibida tocada (P0). En CI, también Decisión sin fila en ADR y Alcance excedido (P1), y Artefacto huérfano e Inventario de componentes (P2). El puntaje es min(100, 40·P0 + 20·P1 + 8·P2): más alto es peor. Qué detecta cada uno y cómo se evita está en Las cinco verificaciones.

Un hook que bloquea por todo se desinstala, y con él se van los cinco checks. En el push se interrumpe a una persona en medio de su trabajo, y sólo lo justifica un P0; en un pull request hay un humano revisando, y el costo de parar es un rebote. Los instrumentos que el detector verifica están en Gobierno del contexto; cómo se adopta el método en un equipo, fase por fase, en Escalar al equipo y costos.