> ## Documentation Index
> Fetch the complete documentation index at: https://docs.befailproof.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Políticas Integradas

> Las 39 políticas integradas que detectan los fallos más comunes de los agentes

failproofai incluye 39 políticas integradas que detectan los fallos más comunes de los agentes. Cada política se activa en un tipo de evento de hook específico y en un nombre de herramienta determinado. Diecinueve políticas aceptan parámetros que permiten ajustar su comportamiento sin necesidad de escribir código. Cinco políticas de flujo de trabajo imponen una cadena commit → push → PR → CI antes de que Claude se detenga.

***

## Descripción general

Las políticas están agrupadas en categorías:

| Categoría                                       | Políticas                                                                                                                                    | Tipo de hook |
| ----------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | ------------ |
| [Comandos peligrosos](#dangerous-commands)      | block-sudo, block-rm-rf, block-curl-pipe-sh, block-failproofai-commands                                                                      | PreToolUse   |
| [Comandos de infraestructura](#infra-commands)  | block-kubectl, block-terraform, block-aws-cli, block-gcloud, block-az-cli, block-helm, block-gh-pipeline                                     | PreToolUse   |
| [Secretos (sanitizadores)](#secrets-sanitizers) | sanitize-jwt, sanitize-api-keys, sanitize-connection-strings, sanitize-private-key-content, sanitize-bearer-tokens                           | PostToolUse  |
| [Entorno](#environment)                         | block-env-files, protect-env-vars                                                                                                            | PreToolUse   |
| [Acceso a archivos](#file-access)               | block-read-outside-cwd, block-secrets-write                                                                                                  | PreToolUse   |
| [Git](#git)                                     | block-push-master, block-work-on-main, block-force-push, warn-git-amend, warn-git-stash-drop, warn-all-files-staged                          | PreToolUse   |
| [Base de datos](#database)                      | warn-destructive-sql, warn-schema-alteration                                                                                                 | PreToolUse   |
| [Advertencias](#warnings)                       | warn-large-file-write, warn-package-publish, warn-background-process, warn-global-package-install                                            | PreToolUse   |
| [Gestores de paquetes](#package-managers)       | prefer-package-manager                                                                                                                       | PreToolUse   |
| [Flujo de trabajo](#workflow)                   | require-commit-before-stop, require-push-before-stop, require-pr-before-stop, require-no-conflicts-before-stop, require-ci-green-before-stop | Stop         |

* **`block-`** — impide que el agente continúe.
* **`warn-`** — proporciona al agente contexto adicional para que pueda corregirse.
* **`sanitize-`** — elimina datos sensibles del resultado de la herramienta antes de que el agente lo vea.

### Espacios de nombres

Cada política reside en un espacio `<namespace>/<name>`. Las políticas integradas pertenecen al
espacio de nombres **`failproofai/`** — por ejemplo, `failproofai/sanitize-jwt`. El
espacio de nombres evita colisiones cuando también se cargan políticas personalizadas o de terceros
con nombres cortos similares.

En la configuración puedes referirte a una política integrada por su nombre corto o su
nombre calificado; ambas formas apuntan a la misma política:

```json theme={null}
{
  "enabledPolicies": [
    "sanitize-jwt",
    "failproofai/block-rm-rf"
  ]
}
```

Si un nombre no contiene `/`, failproofai lo trata como perteneciente al espacio de nombres
predeterminado `failproofai`. Los nombres que ya contienen `/` (p. ej. `myorg/foo`,
`custom/my-hook`) se mantienen tal cual.

* **`require-`** — bloquea el evento Stop hasta que se cumplan las condiciones.

***

<Tip>
  Todas las políticas admiten un campo opcional `hint` en `policyParams`. El hint se añade al mensaje de deny o instruct que ve Claude, proporcionando orientación accionable sin modificar el código de la política. Funciona con políticas integradas, personalizadas y de convención. Consulta [Configuración → hint](/es/configuration#hint-cross-cutting) para más detalles.
</Tip>

***

## Comandos peligrosos

Evita que los agentes ejecuten operaciones difíciles de deshacer o que puedan dañar el sistema anfitrión.

### `block-sudo`

**Evento:** PreToolUse (Bash)\
**Comportamiento por defecto:** Deniega cualquier comando `sudo`.

Bloquea invocaciones que incluyen la palabra clave `sudo`. La coincidencia de patrones se realiza sobre los tokens del comando analizado, no sobre la cadena en bruto, para evitar bypass mediante inyección de operadores de shell.

**Parámetros:**

| Parámetro       | Tipo       | Valor por defecto | Descripción                                                                                                   |
| --------------- | ---------- | ----------------- | ------------------------------------------------------------------------------------------------------------- |
| `allowPatterns` | `string[]` | `[]`              | Prefijos de comandos exactos que están permitidos. Cada entrada se compara contra los tokens argv analizados. |

**Ejemplo:**

```json theme={null}
{
  "policyParams": {
    "block-sudo": {
      "allowPatterns": ["sudo systemctl status", "sudo journalctl"]
    }
  }
}
```

Con esta configuración, `sudo systemctl status nginx` está permitido, pero `sudo rm /etc/hosts` se deniega.

<Note>
  Los patrones se comparan contra tokens analizados, no contra la cadena de comando en bruto. Esto evita bypass mediante operadores de shell añadidos (p. ej. `sudo systemctl status x; rm -rf /` no coincide con `sudo systemctl status *`).
</Note>

***

### `block-rm-rf`

**Evento:** PreToolUse (Bash)\
**Comportamiento por defecto:** Deniega `rm -rf`, `rm -fr` y formas similares de eliminación recursiva.

**Parámetros:**

| Parámetro    | Tipo       | Valor por defecto | Descripción                                                                      |
| ------------ | ---------- | ----------------- | -------------------------------------------------------------------------------- |
| `allowPaths` | `string[]` | `[]`              | Rutas que pueden eliminarse de forma recursiva de manera segura (p. ej. `/tmp`). |

**Ejemplo:**

```json theme={null}
{
  "policyParams": {
    "block-rm-rf": {
      "allowPaths": ["/tmp", "/var/cache"]
    }
  }
}
```

***

### `block-curl-pipe-sh`

**Evento:** PreToolUse (Bash)\
**Comportamiento por defecto:** Deniega `curl <url> | bash`, `curl <url> | sh`, `wget <url> | bash` y patrones similares.

Sin parámetros.

***

### `block-failproofai-commands`

**Evento:** PreToolUse (Bash)\
**Comportamiento por defecto:** Deniega comandos que desinstalarían o deshabilitarían failproofai (p. ej. `npm uninstall failproofai`, `failproofai policies --uninstall`).

Sin parámetros.

***

## Comandos de infraestructura

Impide que los agentes de código ejecuten CLIs de infraestructura o activen pipelines de CI/CD. Todas las políticas de esta categoría están **desactivadas por defecto** (`defaultEnabled: false`) — los agentes que legítimamente necesiten llamar a `kubectl`, `terraform`, etc. no se verán afectados a menos que habilites la política. Cuando está habilitada, cualquier invocación del CLI correspondiente se deniega a menos que el comando coincida con una entrada en `allowPatterns`.

La gramática de patrones es la misma que en [`block-sudo`](#block-sudo): los tokens se comparan contra argv analizado, `*` es un comodín para un token, y cualquier comando que contenga un operador de shell independiente (`&&`, `||`, `|`, `;`) o un token con metacaracteres de shell incrustados se rechaza antes de la comprobación de la lista de permitidos para evitar bypass por inyección.

### `block-kubectl`

**Evento:** PreToolUse (Bash)\
**Comportamiento por defecto:** Deniega cualquier invocación de `kubectl`.

**Parámetros:**

| Parámetro       | Tipo       | Valor por defecto | Descripción                              |
| --------------- | ---------- | ----------------- | ---------------------------------------- |
| `allowPatterns` | `string[]` | `[]`              | Prefijos de comandos kubectl permitidos. |

**Ejemplo:**

```json theme={null}
{
  "policyParams": {
    "block-kubectl": {
      "allowPatterns": ["kubectl get *", "kubectl describe *", "kubectl logs *"]
    }
  }
}
```

Con esta configuración, `kubectl get pods` está permitido pero `kubectl apply -f deploy.yaml` se deniega.

***

### `block-terraform`

**Evento:** PreToolUse (Bash)\
**Comportamiento por defecto:** Deniega cualquier invocación de `terraform` o `tofu` (OpenTofu).

**Parámetros:**

| Parámetro       | Tipo       | Valor por defecto | Descripción                                     |
| --------------- | ---------- | ----------------- | ----------------------------------------------- |
| `allowPatterns` | `string[]` | `[]`              | Prefijos de comandos terraform/tofu permitidos. |

**Ejemplo:**

```json theme={null}
{
  "policyParams": {
    "block-terraform": {
      "allowPatterns": ["terraform plan", "terraform validate", "terraform show *"]
    }
  }
}
```

***

### `block-aws-cli`

**Evento:** PreToolUse (Bash)\
**Comportamiento por defecto:** Deniega cualquier invocación del CLI `aws`.

**Parámetros:**

| Parámetro       | Tipo       | Valor por defecto | Descripción                                  |
| --------------- | ---------- | ----------------- | -------------------------------------------- |
| `allowPatterns` | `string[]` | `[]`              | Prefijos de comandos del CLI aws permitidos. |

**Ejemplo:**

```json theme={null}
{
  "policyParams": {
    "block-aws-cli": {
      "allowPatterns": ["aws s3 ls *", "aws sts get-caller-identity"]
    }
  }
}
```

***

### `block-gcloud`

**Evento:** PreToolUse (Bash)\
**Comportamiento por defecto:** Deniega cualquier invocación del CLI `gcloud` (Google Cloud).

**Parámetros:**

| Parámetro       | Tipo       | Valor por defecto | Descripción                             |
| --------------- | ---------- | ----------------- | --------------------------------------- |
| `allowPatterns` | `string[]` | `[]`              | Prefijos de comandos gcloud permitidos. |

**Ejemplo:**

```json theme={null}
{
  "policyParams": {
    "block-gcloud": {
      "allowPatterns": ["gcloud auth list", "gcloud config list"]
    }
  }
}
```

***

### `block-az-cli`

**Evento:** PreToolUse (Bash)\
**Comportamiento por defecto:** Deniega cualquier invocación del CLI `az` (Azure).

**Parámetros:**

| Parámetro       | Tipo       | Valor por defecto | Descripción                                 |
| --------------- | ---------- | ----------------- | ------------------------------------------- |
| `allowPatterns` | `string[]` | `[]`              | Prefijos de comandos del CLI az permitidos. |

**Ejemplo:**

```json theme={null}
{
  "policyParams": {
    "block-az-cli": {
      "allowPatterns": ["az account show", "az group list"]
    }
  }
}
```

***

### `block-helm`

**Evento:** PreToolUse (Bash)\
**Comportamiento por defecto:** Deniega cualquier invocación de `helm`.

**Parámetros:**

| Parámetro       | Tipo       | Valor por defecto | Descripción                           |
| --------------- | ---------- | ----------------- | ------------------------------------- |
| `allowPatterns` | `string[]` | `[]`              | Prefijos de comandos helm permitidos. |

**Ejemplo:**

```json theme={null}
{
  "policyParams": {
    "block-helm": {
      "allowPatterns": ["helm list", "helm status *"]
    }
  }
}
```

***

### `block-gh-pipeline`

**Evento:** PreToolUse (Bash)\
**Comportamiento por defecto:** Deniega los siguientes subcomandos del CLI `gh` que modifican estado o activan pipelines:

* `gh workflow run`, `gh workflow enable`, `gh workflow disable`
* `gh run rerun`, `gh run cancel`
* `gh pr merge`
* `gh release create`, `gh release delete`
* `gh cache delete`
* `gh secret set`, `gh secret delete`

Los subcomandos de solo lectura de `gh` como `gh pr view`, `gh pr list`, `gh run list`, `gh release view` y `gh api repos/.../...` **no** son interceptados por esta política — son habitualmente necesarios para verificaciones de flujo de trabajo (incluido el propio `require-ci-green-before-stop` de failproofai).

**Parámetros:**

| Parámetro       | Tipo       | Valor por defecto | Descripción                                                              |
| --------------- | ---------- | ----------------- | ------------------------------------------------------------------------ |
| `allowPatterns` | `string[]` | `[]`              | Invocaciones específicas permitidas aunque normalmente serían denegadas. |

**Ejemplo:**

```json theme={null}
{
  "policyParams": {
    "block-gh-pipeline": {
      "allowPatterns": ["gh run rerun *"]
    }
  }
}
```

***

## Secretos (sanitizadores)

Evita que los agentes filtren credenciales en su contexto o salida. Las políticas sanitizadoras se activan en eventos **PostToolUse**. Cuando Claude ejecuta un comando Bash, lee un archivo o llama a cualquier herramienta, estas políticas inspeccionan la salida antes de devolvérsela a Claude. Si se detecta un patrón de secreto, la política devuelve una decisión de deny que impide que la salida sea retornada.

### `sanitize-jwt`

**Evento:** PostToolUse (todas las herramientas)\
**Comportamiento por defecto:** Redacta tokens JWT (tres segmentos base64url separados por `.`).

Sin parámetros.

***

### `sanitize-api-keys`

**Evento:** PostToolUse (todas las herramientas)\
**Comportamiento por defecto:** Redacta formatos comunes de claves de API: Anthropic (`sk-ant-`), OpenAI (`sk-`), GitHub PATs (`ghp_`), claves de acceso AWS (`AKIA`), claves Stripe (`sk_live_`, `sk_test_`) y claves de Google API (`AIza`).

**Parámetros:**

| Parámetro            | Tipo                                 | Valor por defecto | Descripción                                                  |
| -------------------- | ------------------------------------ | ----------------- | ------------------------------------------------------------ |
| `additionalPatterns` | `{ regex: string; label: string }[]` | `[]`              | Patrones regex adicionales que deben tratarse como secretos. |

**Ejemplo:**

```json theme={null}
{
  "policyParams": {
    "sanitize-api-keys": {
      "additionalPatterns": [
        { "regex": "myco_[A-Za-z0-9]{32}", "label": "MyCo internal API key" },
        { "regex": "pat_[0-9a-f]{40}", "label": "Internal PAT" }
      ]
    }
  }
}
```

***

### `sanitize-connection-strings`

**Evento:** PostToolUse (todas las herramientas)\
**Comportamiento por defecto:** Redacta cadenas de conexión a bases de datos que contienen credenciales incrustadas (p. ej. `postgresql://user:password@host/db`).

Sin parámetros.

***

### `sanitize-private-key-content`

**Evento:** PostToolUse (todas las herramientas)\
**Comportamiento por defecto:** Redacta bloques PEM (`-----BEGIN PRIVATE KEY-----`, `-----BEGIN RSA PRIVATE KEY-----`, etc.).

Sin parámetros.

***

### `sanitize-bearer-tokens`

**Evento:** PostToolUse (todas las herramientas)\
**Comportamiento por defecto:** Redacta cabeceras `Authorization: Bearer <token>` donde el token tiene 20 o más caracteres.

Sin parámetros.

***

## Entorno

Protege la configuración sensible del entorno para que los agentes no puedan leerla ni exponerla.

### `block-env-files`

**Evento:** PreToolUse (Bash, Read)\
**Comportamiento por defecto:** Deniega la lectura de archivos `.env` mediante `cat .env`, llamadas a la herramienta `Read` con `.env` como ruta de archivo, etc.

No bloquea `.envrc` ni otros archivos relacionados con el entorno — solo archivos cuyo nombre exacto sea `.env`.

Sin parámetros.

***

### `protect-env-vars`

**Evento:** PreToolUse (Bash)\
**Comportamiento por defecto:** Deniega comandos que imprimen variables de entorno: `printenv`, `env`, `echo $VAR`.

Sin parámetros.

***

## Acceso a archivos

Mantiene a los agentes dentro de los límites del proyecto y alejados de archivos sensibles.

### `block-read-outside-cwd`

**Evento:** PreToolUse (Read, Bash)\
**Comportamiento por defecto:** Deniega la lectura de archivos fuera de la raíz del proyecto. El límite es `CLAUDE_PROJECT_DIR` (establecido una vez por sesión por Claude Code), con un fallback al directorio de trabajo actual de la sesión cuando esa variable no está definida. Usar la raíz del proyecto en lugar del `cwd` activo significa que el límite se mantiene estable incluso después de que Claude haga `cd` a un subdirectorio.

**Parámetros:**

| Parámetro    | Tipo       | Valor por defecto | Descripción                                                                        |
| ------------ | ---------- | ----------------- | ---------------------------------------------------------------------------------- |
| `allowPaths` | `string[]` | `[]`              | Prefijos de rutas absolutas permitidos aunque estén fuera de la raíz del proyecto. |

**Ejemplo:**

```json theme={null}
{
  "policyParams": {
    "block-read-outside-cwd": {
      "allowPaths": ["/shared/data", "/opt/company/config"]
    }
  }
}
```

***

### `block-secrets-write`

**Evento:** PreToolUse (Write, Edit)\
**Comportamiento por defecto:** Deniega escrituras en archivos comúnmente utilizados para claves privadas y certificados: `id_rsa`, `id_ed25519`, `*.key`, `*.pem`, `*.p12`, `*.pfx`.

**Parámetros:**

| Parámetro            | Tipo       | Valor por defecto | Descripción                                                         |
| -------------------- | ---------- | ----------------- | ------------------------------------------------------------------- |
| `additionalPatterns` | `string[]` | `[]`              | Patrones de nombre de archivo adicionales (estilo glob) a bloquear. |

**Ejemplo:**

```json theme={null}
{
  "policyParams": {
    "block-secrets-write": {
      "additionalPatterns": [".token", ".secret"]
    }
  }
}
```

***

## Git

Previene pushes accidentales, force-pushes y errores de rama que son difíciles de deshacer.

### `block-push-master`

**Evento:** PreToolUse (Bash)\
**Comportamiento por defecto:** Deniega `git push origin main` y `git push origin master`.

**Parámetros:**

| Parámetro           | Tipo       | Valor por defecto    | Descripción                                                     |
| ------------------- | ---------- | -------------------- | --------------------------------------------------------------- |
| `protectedBranches` | `string[]` | `["main", "master"]` | Nombres de ramas a las que no se puede hacer push directamente. |

**Ejemplo:**

```json theme={null}
{
  "policyParams": {
    "block-push-master": {
      "protectedBranches": ["main", "master", "release", "prod"]
    }
  }
}
```

<Tip>
  Para permitir push a todas las ramas (deshabilitando efectivamente esta política sin eliminarla de `enabledPolicies`), establece `protectedBranches: []`.
</Tip>

***

### `block-work-on-main`

**Evento:** PreToolUse (Bash)\
**Comportamiento por defecto:** Deniega `git commit`, `git merge`, `git rebase` y `git cherry-pick` mientras el árbol de trabajo esté en `main` o `master`. La creación y el cambio de ramas (`git checkout`, `git checkout -b`, `git switch`, `git switch -c`) no se ven afectados.

**Parámetros:**

| Parámetro           | Tipo       | Valor por defecto    | Descripción                                                             |
| ------------------- | ---------- | -------------------- | ----------------------------------------------------------------------- |
| `protectedBranches` | `string[]` | `["main", "master"]` | Nombres de ramas en las que se deniega commit/merge/rebase/cherry-pick. |

***

### `block-force-push`

**Evento:** PreToolUse (Bash)\
**Comportamiento por defecto:** Deniega `git push --force` y `git push -f`.

Sin parámetros específicos de política. Usa el campo transversal [`hint`](/es/configuration#hint-cross-cutting) para sugerir alternativas:

```json theme={null}
{
  "policyParams": {
    "block-force-push": {
      "hint": "Create a new branch from your current HEAD (e.g. `git checkout -b <new-branch>`) and push that instead."
    }
  }
}
```

***

### `warn-git-amend`

**Evento:** PreToolUse (Bash)\
**Comportamiento por defecto:** Instruye a Claude a proceder con cautela al ejecutar `git commit --amend`. No bloquea el comando.

Sin parámetros.

***

### `warn-git-stash-drop`

**Evento:** PreToolUse (Bash)\
**Comportamiento por defecto:** Instruye a Claude a confirmar antes de ejecutar `git stash drop`. No bloquea el comando.

Sin parámetros.

***

### `warn-all-files-staged`

**Evento:** PreToolUse (Bash)\
**Comportamiento por defecto:** Instruye a Claude a revisar qué está añadiendo al área de stage cuando ejecuta `git add -A` o `git add .`. No bloquea el comando.

Sin parámetros.

***

## Base de datos

Intercepta operaciones SQL destructivas antes de que se ejecuten en tu base de datos.

### `warn-destructive-sql`

**Evento:** PreToolUse (Bash)\
**Comportamiento por defecto:** Instruye a Claude a confirmar antes de ejecutar SQL que contenga `DROP TABLE`, `DROP DATABASE` o `DELETE` sin cláusula `WHERE`.

Sin parámetros.

***

### `warn-schema-alteration`

**Evento:** PreToolUse (Bash)\
**Comportamiento por defecto:** Instruye a Claude a confirmar antes de ejecutar sentencias `ALTER TABLE`.

Sin parámetros.

***

## Advertencias

Proporciona a los agentes contexto adicional antes de operaciones potencialmente arriesgadas pero no destructivas.

### `warn-large-file-write`

**Evento:** PreToolUse (Write)\
**Comportamiento por defecto:** Instruye a Claude a confirmar antes de escribir archivos de más de 1024 KB.

**Parámetros:**

| Parámetro     | Tipo     | Valor por defecto | Descripción                                                                          |
| ------------- | -------- | ----------------- | ------------------------------------------------------------------------------------ |
| `thresholdKb` | `number` | `1024`            | Umbral de tamaño de archivo en kilobytes a partir del cual se emite una advertencia. |

**Ejemplo:**

```json theme={null}
{
  "policyParams": {
    "warn-large-file-write": {
      "thresholdKb": 256
    }
  }
}
```

<Note>
  El manejador de hooks impone un límite de 1 MB en stdin para los payloads. Para probar esta política con contenido pequeño, establece `thresholdKb` a un valor muy por debajo de 1024.
</Note>

***

### `warn-package-publish`

**Evento:** PreToolUse (Bash)\
**Comportamiento por defecto:** Instruye a Claude a confirmar antes de ejecutar `npm publish`.

Sin parámetros.

***

### `warn-background-process`

**Evento:** PreToolUse (Bash)\
**Comportamiento por defecto:** Instruye a Claude a tener cuidado al lanzar procesos en segundo plano mediante `nohup`, `&`, `disown` o `screen`.

Sin parámetros.

***

### `warn-global-package-install`

**Evento:** PreToolUse (Bash)\
**Comportamiento por defecto:** Instruye a Claude a confirmar antes de ejecutar `npm install -g`, `yarn global add` o `pip install` sin un entorno virtual.

Sin parámetros.

***

## Gestores de paquetes

Impone qué gestores de paquetes puede utilizar el agente.

### `prefer-package-manager`

**Evento:** PreToolUse (Bash)\
**Comportamiento por defecto:** Desactivado. Cuando está habilitado, bloquea cualquier comando de gestor de paquetes que no esté en la lista `allowed` e indica a Claude que reescriba el comando usando un gestor permitido.

Detecta: pip, pip3, python -m pip, npm, npx, yarn, pnpm, pnpx, bun, bunx, uv, poetry, pipenv, conda, cargo.

| Parámetro | Tipo      | Valor por defecto | Descripción                                                                                                                                                      |
| --------- | --------- | ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `allowed` | string\[] | `[]`              | Nombres de gestores de paquetes permitidos. Cualquier gestor detectado que no esté en esta lista será bloqueado. Cuando está vacía, la política no tiene efecto. |
| `blocked` | string\[] | `[]`              | Nombres de gestores adicionales a bloquear más allá de la lista integrada (p. ej. `['pdm', 'pipx']`).                                                            |

La lista de bloqueo integrada incluye: pip, pip3, npm, npx, yarn, pnpm, pnpx, bun, bunx, uv, poetry, pipenv, conda, cargo. Usa `blocked` para añadir gestores que no están en esta lista.

**Ejemplo de configuración:**

```json theme={null}
{
  "enabledPolicies": ["prefer-package-manager"],
  "policyParams": {
    "prefer-package-manager": {
      "allowed": ["uv", "bun"],
      "blocked": ["pdm", "pipx"]
    }
  }
}
```

Con esta configuración, tanto `pip install flask` como `pdm install flask` se deniegan con un mensaje que indica a Claude que use `uv` o `bun` en su lugar. Comandos como `uv pip install flask` están permitidos porque `uv` está en la lista de permitidos y se comprueba primero.

***

## Comportamiento de la IA

Detecta cuándo los agentes se quedan atascados o se comportan de forma inesperada.

### `warn-repeated-tool-calls`

**Evento:** PreToolUse (todas las herramientas)\
**Comportamiento por defecto:** Instruye a Claude a reconsiderar cuando la misma herramienta se llama 3 o más veces con parámetros idénticos — señal habitual de que el agente está atrapado en un bucle.

Sin parámetros.

***

## Flujo de trabajo

Impone un flujo de trabajo disciplinado al final de la sesión. Estas políticas se activan en el evento **Stop** y deniegan al agente detenerse hasta que se cumpla cada condición. Siguen una cadena de dependencias natural: commit → push → PR → CI. Si una política deniega, las políticas posteriores en la cadena se omiten (la denegación cortocircuita la cadena).

Todas las políticas de flujo de trabajo son **fail-open**: si la herramienta requerida no está disponible (p. ej. `gh` no está instalado, no hay remote de git), la política permite con un mensaje informativo explicando por qué se omitió la comprobación.

### Semántica de Stop por CLI

La aplicación del Stop se ve ligeramente diferente entre los seis CLIs compatibles porque cada uno expone un contrato de hook distinto para "el agente ha terminado". El **resultado** es el mismo — el agente no puede detenerse mientras una condición de flujo de trabajo esté fallando — pero los **mecanismos** difieren. La tabla a continuación resume esto; solo Pi tiene un comportamiento visible para el usuario que vale la pena entender antes de habilitar una política `require-*-before-stop`.

| CLI                      | Cuándo se activa la condición                | Lo que ves                                                                                                                                                                                                                                                                                                                                                                                      |
| ------------------------ | -------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Claude Code              | En el mismo bucle del agente, inmediatamente | Claude continúa trabajando — soluciona el problema y luego intenta terminar de nuevo. No hay interrupción visible para ti.                                                                                                                                                                                                                                                                      |
| Codex                    | En el mismo bucle del agente, inmediatamente | Igual que Claude.                                                                                                                                                                                                                                                                                                                                                                               |
| GitHub Copilot CLI       | En el mismo bucle del agente, inmediatamente | Igual que Claude (usa el canal de reintento `{decision:"block", reason}` de Copilot — verificado empíricamente contra Copilot CLI 1.0.41).                                                                                                                                                                                                                                                      |
| Cursor Agent             | En el mismo bucle del agente, inmediatamente | Igual que Claude (usa el canal `{followup_message}` de Cursor — limitado a `loop_limit`, por defecto 5 reintentos).                                                                                                                                                                                                                                                                             |
| OpenCode                 | En el mismo bucle del agente, inmediatamente | Igual que Claude (usa la llamada SDK `client.session.prompt(...)` de OpenCode enrutada a través de `hookSpecificOutput.additionalContext`).                                                                                                                                                                                                                                                     |
| **Pi (pi-coding-agent)** | **En el siguiente turno del usuario**        | **Pi se detiene visiblemente** cuando se activa la condición — su bucle de agente termina y se te devuelve el prompt. La condición se activa la próxima vez que envíes un prompt: failproofai antepone una directiva `MANDATORY ACTION REQUIRED` al system prompt de ese turno, instruyendo al LLM a completar el paso del flujo de trabajo (commit, push, etc.) antes de hacer lo que pediste. |

<Note>
  **Limitación de Pi.** El `AgentEndEvent` de Pi (el equivalente upstream del hook `Stop` de Claude) no tiene tipo Result — para cuando se activa, el bucle del agente de Pi ya ha terminado. Pi no puede ser forzado a reintentar el mismo bucle como Claude / Copilot / Cursor / OpenCode. failproofai traslada la condición al evento `before_agent_start` de Pi (que se activa después del siguiente prompt del usuario) para que la comprobación del flujo de trabajo siga siendo efectiva, solo en el siguiente turno en lugar del actual.

  **Lo que esto significa en la práctica:**

  * Después de que Pi se detenga, el motivo de la denegación se captura en memoria indexado por el id de sesión de Pi. El siguiente prompt que envíes en el mismo proceso de Pi lo drena: el LLM ve la directiva `MANDATORY ACTION REQUIRED` al inicio de su system prompt, hace el commit (o push / abre el PR / espera a CI), y solo entonces continúa con tu solicitud. El motivo de denegación capturado es de un solo uso — una vez drenado, la condición queda libre.
  * La condición está limitada por el tiempo de vida del proceso de Pi. Si haces `Ctrl+C` en Pi o sales entre turnos, la entrada en memoria se descarta junto con el proceso y la condición se pierde. Claude, Copilot, Cursor y OpenCode tienen el mismo límite (matar el agente hace que se pierda la condición) — Pi simplemente lo hace más visible porque el agente termina visiblemente antes de que se active la condición.
  * Una denegación pendiente también se limpia en `session_shutdown` por cualquier motivo (`new` / `resume` / `fork` / `quit`), de modo que una condición obsoleta de una sesión anterior no puede filtrarse a una sesión nueva iniciada en el mismo proceso de Pi.

  Si necesitas el reintento en el mismo bucle al estilo Claude, ejecuta tus políticas de `Stop` bajo cualquiera de los otros cinco CLIs compatibles. Estamos siguiendo Pi upstream para un futuro tipo Result en `AgentEndEvent` que nos permitiría cerrar esta brecha.
</Note>

### `require-commit-before-stop`

**Evento:** Stop\
**Comportamiento por defecto:** Deniega la detención cuando hay cambios sin confirmar (archivos modificados, en stage o sin seguimiento). Devuelve un mensaje informativo cuando el directorio de trabajo está limpio.

Sin parámetros.

***

### `require-push-before-stop`

**Evento:** Stop\
**Comportamiento por defecto:** Deniega la detención cuando hay commits sin subir o cuando la rama actual no tiene una rama de seguimiento remota. Sugiere `git push -u` para crear una rama de seguimiento si es necesario. Falla de forma abierta si no hay remote configurado.

**Parámetros:**

| Parámetro | Tipo     | Valor por defecto | Descripción                          |
| --------- | -------- | ----------------- | ------------------------------------ |
| `remote`  | `string` | `"origin"`        | Nombre del remote al que hacer push. |

**Ejemplo:**

```json theme={null}
{
  "policyParams": {
    "require-push-before-stop": {
      "remote": "upstream"
    }
  }
}
```

***

### `require-pr-before-stop`

**Evento:** Stop\
**Comportamiento por defecto:** Deniega la detención cuando no existe un pull request para la rama actual, o cuando el PR existente está cerrado sin haberse fusionado. Instruye a Claude a crear un PR con `gh pr create`. Cuando el PR está **fusionado**, la política lo permite (el trabajo está publicado) y el mensaje sugiere cambiar de la rama (`git checkout main && git pull`).

Sin parámetros.

<Note>
  Esta política requiere que el [CLI de GitHub](https://cli.github.com/) (`gh`) esté instalado y autenticado.
  Ejecuta `gh auth login` con un token de acceso personal que tenga el scope `repo` para acceso de lectura a
  pull requests. Si `gh` no está instalado o no está autenticado, la política falla de forma abierta e informa del motivo a Claude.
</Note>

***

### `require-no-conflicts-before-stop`

**Evento:** Stop\
**Comportamiento por defecto:** Deniega la detención cuando la rama actual no puede fusionarse limpiamente con la rama base. La política primero confirma que existe un PR `OPEN` en GitHub para la rama — sin uno, no hay un destino de fusión que aplicar, por lo que toda la política cortocircuita a allow. Una vez confirmado un PR `OPEN`, se ejecutan dos comprobaciones independientes:

1. **Local** — `git merge-tree --write-tree --name-only origin/<baseBranch> HEAD`. En caso de conflicto, el mensaje de denegación nombra los archivos conflictivos para que Claude sepa exactamente qué resolver.
2. **GitHub** — reutiliza el resultado de `gh pr view --json mergeable,state` ya obtenido en la precomprobación. Detecta conflictos que un `origin/<baseBranch>` local obsoleto podría pasar por alto (p. ej. alguien fusionó un PR conflictivo en `main` desde el último fetch). Un resultado `CONFLICTING` deniega. Un resultado `UNKNOWN` también deniega e instruye a Claude a esperar \~10 segundos y volver a comprobar antes de intentar detenerse de nuevo — esto previene falsos negativos mientras GitHub recalcula.

Se omite completamente (permite) cuando: `gh` no está instalado, no existe PR para la rama, el estado del PR no es `OPEN` (p. ej. `MERGED`, `CLOSED`), o `gh pr view` devuelve una salida no parseable. También falla de forma abierta cuando `origin/<baseBranch>` falta localmente o cuando no hay commits por delante de la base — esos fallbacks de Capa 1 aún consultan la fusionabilidad del PR en caché antes de permitir.

**Parámetros:**

| Parámetro    | Tipo     | Valor por defecto | Descripción                                       |
| ------------ | -------- | ----------------- | ------------------------------------------------- |
| `baseBranch` | `string` | `"main"`          | Rama base contra la que comprobar los conflictos. |

<Note>
  El CLI de GitHub (`gh`) es necesario para esta política. La política usa `gh pr view` para confirmar
  que existe un PR `OPEN` antes de ejecutar cualquier comprobación de conflictos — sin `gh`, la política
  cortocircuita a allow. Ejecuta `gh auth login` con un token de acceso personal que tenga el scope `repo`
  para acceso de lectura a pull requests.
</Note>

***

### `require-ci-green-before-stop`

**Evento:** Stop\
**Comportamiento por defecto:** Deniega la detención cuando las comprobaciones de CI están fallando o aún en ejecución en la rama actual. Comprueba tanto los workflow runs de GitHub Actions como las comprobaciones de bots de terceros (p. ej. CodeRabbit, SonarCloud, Codecov). Trata las conclusiones `skipped`, `cancelled` y `neutral` como no fallidas (esta última cubre, por ejemplo, alertas de Socket Security en PRs de colaboradores externos, donde la aplicación intencionalmente reporta neutral en lugar de success/failure). Devuelve un mensaje informativo cuando todas las comprobaciones pasan.

Sin parámetros.

<Note>
  Esta política requiere que el [CLI de GitHub](https://cli.github.com/) (`gh`) esté instalado y autenticado.
  Ejecuta `gh auth login` con un token de acceso personal que tenga el scope `repo` para acceso de lectura a
  workflow runs de Actions y la API de Checks. Si `gh` no está instalado o no está autenticado, la política falla de forma abierta e informa del motivo a Claude.
</Note>

***

***

## Desactivar políticas individuales

Elimina una política específica de `enabledPolicies` en tu configuración, o desactívala desde la pestaña Policies del dashboard.

```json theme={null}
{
  "enabledPolicies": [
    "block-rm-rf",
    "sanitize-api-keys"
  ]
}
```

Las políticas que no aparecen en `enabledPolicies` no se ejecutan, aunque existan entradas para ellas en `policyParams`.
