failproofai 0.0.5 → 0.0.6-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (179) hide show
  1. package/.next/standalone/.failproofai/policies/review-policies.mjs +112 -0
  2. package/.next/standalone/.failproofai/policies/workflow-policies.mjs +2 -1
  3. package/.next/standalone/.next/BUILD_ID +1 -1
  4. package/.next/standalone/.next/build-manifest.json +5 -5
  5. package/.next/standalone/.next/prerender-manifest.json +3 -3
  6. package/.next/standalone/.next/required-server-files.json +1 -1
  7. package/.next/standalone/.next/server/app/_global-error/page/build-manifest.json +2 -2
  8. package/.next/standalone/.next/server/app/_global-error/page/server-reference-manifest.json +1 -1
  9. package/.next/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
  10. package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  11. package/.next/standalone/.next/server/app/_global-error.html +1 -1
  12. package/.next/standalone/.next/server/app/_global-error.rsc +7 -7
  13. package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +2 -2
  14. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +7 -7
  15. package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +3 -3
  16. package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +3 -3
  17. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  18. package/.next/standalone/.next/server/app/_not-found/page/build-manifest.json +2 -2
  19. package/.next/standalone/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  20. package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  21. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  22. package/.next/standalone/.next/server/app/_not-found.html +2 -2
  23. package/.next/standalone/.next/server/app/_not-found.rsc +15 -15
  24. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +15 -15
  25. package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +4 -4
  26. package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +10 -10
  27. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
  28. package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +3 -3
  29. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  30. package/.next/standalone/.next/server/app/index.html +1 -1
  31. package/.next/standalone/.next/server/app/index.rsc +15 -15
  32. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  33. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +15 -15
  34. package/.next/standalone/.next/server/app/index.segments/_head.segment.rsc +4 -4
  35. package/.next/standalone/.next/server/app/index.segments/_index.segment.rsc +10 -10
  36. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  37. package/.next/standalone/.next/server/app/page/build-manifest.json +2 -2
  38. package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
  39. package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
  40. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  41. package/.next/standalone/.next/server/app/policies/page/build-manifest.json +2 -2
  42. package/.next/standalone/.next/server/app/policies/page/server-reference-manifest.json +8 -8
  43. package/.next/standalone/.next/server/app/policies/page.js.nft.json +1 -1
  44. package/.next/standalone/.next/server/app/policies/page_client-reference-manifest.js +1 -1
  45. package/.next/standalone/.next/server/app/project/[name]/page/build-manifest.json +2 -2
  46. package/.next/standalone/.next/server/app/project/[name]/page/server-reference-manifest.json +1 -1
  47. package/.next/standalone/.next/server/app/project/[name]/page.js.nft.json +1 -1
  48. package/.next/standalone/.next/server/app/project/[name]/page_client-reference-manifest.js +1 -1
  49. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/build-manifest.json +2 -2
  50. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/react-loadable-manifest.json +2 -2
  51. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/server-reference-manifest.json +2 -2
  52. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js.nft.json +1 -1
  53. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page_client-reference-manifest.js +1 -1
  54. package/.next/standalone/.next/server/app/projects/page/build-manifest.json +2 -2
  55. package/.next/standalone/.next/server/app/projects/page/server-reference-manifest.json +1 -1
  56. package/.next/standalone/.next/server/app/projects/page.js.nft.json +1 -1
  57. package/.next/standalone/.next/server/app/projects/page_client-reference-manifest.js +1 -1
  58. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0g72weg._.js +1 -1
  59. package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_0z7w.hh._.js +1 -1
  60. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__092s1ta._.js +2 -2
  61. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__09icjsf._.js +2 -2
  62. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0g.lg8b._.js +2 -2
  63. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0h..k-e._.js +2 -2
  64. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0okos0k._.js +2 -2
  65. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0a~g15g._.js → [root-of-the-server]__0rh.18_._.js} +2 -2
  66. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0w6l33k._.js +6 -6
  67. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0qn95h3._.js → [root-of-the-server]__0~kmh8w._.js} +2 -2
  68. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__11pa2ra._.js +2 -2
  69. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__12t-wym._.js +2 -2
  70. package/.next/standalone/.next/server/chunks/ssr/_10lm7or._.js +2 -2
  71. package/.next/standalone/.next/server/chunks/ssr/app_global-error_tsx_0xerkr6._.js +1 -1
  72. package/.next/standalone/.next/server/chunks/ssr/app_policies_hooks-client_tsx_0q-m0y-._.js +1 -1
  73. package/.next/standalone/.next/server/middleware-build-manifest.js +5 -5
  74. package/.next/standalone/.next/server/pages/404.html +2 -2
  75. package/.next/standalone/.next/server/pages/500.html +1 -1
  76. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  77. package/.next/standalone/.next/server/server-reference-manifest.json +9 -9
  78. package/.next/standalone/.next/static/chunks/{0sme4lkv.tgn-.js → 01b~z8f1ws0rk.js} +1 -1
  79. package/.next/standalone/.next/static/chunks/{0lgbwkfqmnsmc.js → 03rz6ykw-a2xi.js} +1 -1
  80. package/.next/standalone/.next/static/chunks/{17manv47o-~wp.js → 08t08igdql9yt.js} +1 -1
  81. package/.next/standalone/.next/static/chunks/09_k80d~cq2wg.js +4 -0
  82. package/.next/standalone/.next/static/chunks/{0ksdlt_1hucdm.js → 0bvhsa6zva2o..js} +1 -1
  83. package/.next/standalone/.next/static/chunks/{09ikntpt2-o9b.js → 0gbf4cphy8ksq.js} +1 -1
  84. package/.next/standalone/.next/static/chunks/{0yumumfzx_f27.js → 0v.yd0kg_ld3r.js} +1 -1
  85. package/.next/standalone/.next/static/chunks/{13juklu.vksks.js → 0wlyoif4_kj_t.js} +1 -1
  86. package/.next/standalone/.next/static/chunks/{09e7drilkf1sn.js → 12simlrcfk3g2.js} +1 -1
  87. package/.next/standalone/.next/static/chunks/{0em7tspi4kylh.js → 12~yi9oj8av8p.js} +2 -2
  88. package/.next/standalone/.next/static/chunks/{turbopack-0r26pc8h0y_-e.js → turbopack-0o7k.hakttp4k.js} +1 -1
  89. package/.next/standalone/CHANGELOG.md +13 -0
  90. package/.next/standalone/README.md +2 -2
  91. package/.next/standalone/bun.lock +43 -85
  92. package/.next/standalone/dist/cli.mjs +107 -3
  93. package/.next/standalone/docs/ar/architecture.mdx +65 -64
  94. package/.next/standalone/docs/ar/configuration.mdx +42 -42
  95. package/.next/standalone/docs/ar/custom-policies.mdx +62 -64
  96. package/.next/standalone/docs/built-in-policies.mdx +37 -0
  97. package/.next/standalone/docs/custom-policies.mdx +1 -1
  98. package/.next/standalone/docs/de/architecture.mdx +92 -92
  99. package/.next/standalone/docs/de/configuration.mdx +34 -34
  100. package/.next/standalone/docs/de/custom-policies.mdx +49 -50
  101. package/.next/standalone/docs/es/architecture.mdx +72 -72
  102. package/.next/standalone/docs/es/configuration.mdx +25 -25
  103. package/.next/standalone/docs/es/custom-policies.mdx +48 -49
  104. package/.next/standalone/docs/examples.mdx +54 -0
  105. package/.next/standalone/docs/fr/architecture.mdx +53 -53
  106. package/.next/standalone/docs/fr/configuration.mdx +25 -25
  107. package/.next/standalone/docs/fr/custom-policies.mdx +42 -43
  108. package/.next/standalone/docs/getting-started.mdx +52 -0
  109. package/.next/standalone/docs/he/architecture.mdx +66 -66
  110. package/.next/standalone/docs/he/configuration.mdx +53 -52
  111. package/.next/standalone/docs/he/custom-policies.mdx +72 -73
  112. package/.next/standalone/docs/hi/architecture.mdx +106 -106
  113. package/.next/standalone/docs/hi/configuration.mdx +39 -39
  114. package/.next/standalone/docs/hi/custom-policies.mdx +75 -76
  115. package/.next/standalone/docs/i18n/README.ar.md +66 -66
  116. package/.next/standalone/docs/i18n/README.de.md +38 -38
  117. package/.next/standalone/docs/i18n/README.es.md +38 -38
  118. package/.next/standalone/docs/i18n/README.fr.md +42 -42
  119. package/.next/standalone/docs/i18n/README.he.md +67 -67
  120. package/.next/standalone/docs/i18n/README.hi.md +70 -70
  121. package/.next/standalone/docs/i18n/README.it.md +62 -62
  122. package/.next/standalone/docs/i18n/README.ja.md +54 -54
  123. package/.next/standalone/docs/i18n/README.ko.md +58 -58
  124. package/.next/standalone/docs/i18n/README.pt-br.md +43 -43
  125. package/.next/standalone/docs/i18n/README.ru.md +69 -69
  126. package/.next/standalone/docs/i18n/README.tr.md +76 -76
  127. package/.next/standalone/docs/i18n/README.vi.md +70 -70
  128. package/.next/standalone/docs/i18n/README.zh.md +52 -52
  129. package/.next/standalone/docs/it/architecture.mdx +54 -53
  130. package/.next/standalone/docs/it/configuration.mdx +44 -45
  131. package/.next/standalone/docs/it/custom-policies.mdx +76 -78
  132. package/.next/standalone/docs/ja/architecture.mdx +93 -93
  133. package/.next/standalone/docs/ja/configuration.mdx +47 -47
  134. package/.next/standalone/docs/ja/custom-policies.mdx +62 -63
  135. package/.next/standalone/docs/ko/architecture.mdx +66 -66
  136. package/.next/standalone/docs/ko/configuration.mdx +35 -35
  137. package/.next/standalone/docs/ko/custom-policies.mdx +71 -72
  138. package/.next/standalone/docs/pt-br/architecture.mdx +55 -55
  139. package/.next/standalone/docs/pt-br/configuration.mdx +35 -35
  140. package/.next/standalone/docs/pt-br/custom-policies.mdx +60 -61
  141. package/.next/standalone/docs/ru/architecture.mdx +59 -60
  142. package/.next/standalone/docs/ru/configuration.mdx +52 -53
  143. package/.next/standalone/docs/ru/custom-policies.mdx +68 -69
  144. package/.next/standalone/docs/tr/architecture.mdx +124 -124
  145. package/.next/standalone/docs/tr/configuration.mdx +45 -46
  146. package/.next/standalone/docs/tr/custom-policies.mdx +75 -75
  147. package/.next/standalone/docs/vi/architecture.mdx +65 -64
  148. package/.next/standalone/docs/vi/configuration.mdx +41 -41
  149. package/.next/standalone/docs/vi/custom-policies.mdx +68 -69
  150. package/.next/standalone/docs/zh/architecture.mdx +67 -67
  151. package/.next/standalone/docs/zh/configuration.mdx +34 -34
  152. package/.next/standalone/docs/zh/custom-policies.mdx +53 -54
  153. package/.next/standalone/node_modules/@next/env/package.json +1 -1
  154. package/.next/standalone/node_modules/next/dist/build/swc/index.js +1 -1
  155. package/.next/standalone/node_modules/next/dist/compiled/next-server/pages-turbo.runtime.prod.js +7 -7
  156. package/.next/standalone/node_modules/next/dist/lib/patch-incorrect-lockfile.js +3 -3
  157. package/.next/standalone/node_modules/next/dist/server/config-schema.js +10 -2
  158. package/.next/standalone/node_modules/next/dist/server/config.js +1 -1
  159. package/.next/standalone/node_modules/next/dist/server/dev/hot-reloader-turbopack.js +2 -2
  160. package/.next/standalone/node_modules/next/dist/server/dev/hot-reloader-webpack.js +1 -1
  161. package/.next/standalone/node_modules/next/dist/server/lib/app-info-log.js +1 -1
  162. package/.next/standalone/node_modules/next/dist/server/lib/start-server.js +1 -1
  163. package/.next/standalone/node_modules/next/dist/server/render.js +27 -20
  164. package/.next/standalone/node_modules/next/dist/shared/lib/errors/canary-only-config-error.js +1 -1
  165. package/.next/standalone/node_modules/next/dist/telemetry/anonymous-meta.js +1 -1
  166. package/.next/standalone/node_modules/next/dist/telemetry/events/swc-load-failure.js +1 -1
  167. package/.next/standalone/node_modules/next/dist/telemetry/events/version.js +2 -2
  168. package/.next/standalone/node_modules/next/package.json +15 -15
  169. package/.next/standalone/package.json +2 -2
  170. package/.next/standalone/server.js +1 -1
  171. package/.next/standalone/src/hooks/builtin-policies.ts +131 -0
  172. package/README.md +2 -2
  173. package/dist/cli.mjs +107 -3
  174. package/package.json +2 -2
  175. package/src/hooks/builtin-policies.ts +131 -0
  176. package/.next/standalone/.next/static/chunks/0_yayar~bpphd.js +0 -4
  177. /package/.next/standalone/.next/static/{hYQM6iCWnF1W5XDpsIRhV → CkmOT-ZvDN-sVULinGVKT}/_buildManifest.js +0 -0
  178. /package/.next/standalone/.next/static/{hYQM6iCWnF1W5XDpsIRhV → CkmOT-ZvDN-sVULinGVKT}/_clientMiddlewareManifest.js +0 -0
  179. /package/.next/standalone/.next/static/{hYQM6iCWnF1W5XDpsIRhV → CkmOT-ZvDN-sVULinGVKT}/_ssgManifest.js +0 -0
@@ -4,7 +4,7 @@ description: "Formato del archivo de configuración, sistema de tres ámbitos y
4
4
  icon: gear
5
5
  ---
6
6
 
7
- failproofai utiliza archivos de configuración JSON para controlar qué políticas están activas, cómo se comportan y desde dónde se cargan las políticas personalizadas. La configuración está diseñada para compartirse fácilmente con tu equipo: confírmala en tu repositorio y todos los desarrolladores tendrán la misma red de seguridad para el agente.
7
+ failproofai utiliza archivos de configuración JSON para controlar qué políticas están activas, cómo se comportan y desde dónde se cargan las políticas personalizadas. La configuración está diseñada para compartirse fácilmente con tu equipo: confírmala en tu repositorio y todos los desarrolladores obtendrán la misma red de seguridad para el agente.
8
8
 
9
9
  ---
10
10
 
@@ -14,15 +14,15 @@ Existen tres ámbitos de configuración, evaluados en orden de prioridad:
14
14
 
15
15
  | Ámbito | Ruta del archivo | Propósito |
16
16
  |--------|-----------------|-----------|
17
- | **project** | `.failproofai/policies-config.json` | Configuración por repositorio, confirmada en control de versiones |
17
+ | **project** | `.failproofai/policies-config.json` | Configuración por repositorio, confirmada en el control de versiones |
18
18
  | **local** | `.failproofai/policies-config.local.json` | Anulaciones personales por repositorio, ignoradas por git |
19
19
  | **global** | `~/.failproofai/policies-config.json` | Valores predeterminados a nivel de usuario para todos los proyectos |
20
20
 
21
- Cuando failproofai recibe un evento de hook, carga y fusiona los tres archivos que existen en el directorio de trabajo actual.
21
+ Cuando failproofai recibe un evento de hook, carga y fusiona los tres archivos que existen para el directorio de trabajo actual.
22
22
 
23
23
  ### Reglas de fusión
24
24
 
25
- **`enabledPolicies`** la unión de los tres ámbitos. Una política habilitada en cualquier nivel estará activa.
25
+ **`enabledPolicies`** - la unión de los tres ámbitos. Una política habilitada en cualquier nivel está activa.
26
26
 
27
27
  ```text
28
28
  project: ["block-sudo"]
@@ -32,13 +32,13 @@ global: ["block-sudo", "sanitize-api-keys"]
32
32
  resolved: ["block-sudo", "block-rm-rf", "sanitize-api-keys"] ← unión sin duplicados
33
33
  ```
34
34
 
35
- **`policyParams`** el primer ámbito que defina parámetros para una política determinada gana por completo. No se realiza una fusión profunda de los valores dentro de los parámetros de una política.
35
+ **`policyParams`** - el primer ámbito que define los parámetros para una política determinada gana completamente. No hay fusión profunda de valores dentro de los parámetros de una política.
36
36
 
37
37
  ```text
38
38
  project: block-sudo → { allowPatterns: ["sudo apt-get update"] }
39
39
  global: block-sudo → { allowPatterns: ["sudo systemctl status"] }
40
40
 
41
- resolved: { allowPatterns: ["sudo apt-get update"] } ← gana project, se ignora global
41
+ resolved: { allowPatterns: ["sudo apt-get update"] } ← project gana, global ignorado
42
42
  ```
43
43
 
44
44
  ```text
@@ -46,12 +46,12 @@ project: (sin entrada block-sudo)
46
46
  local: (sin entrada block-sudo)
47
47
  global: block-sudo → { allowPatterns: ["sudo systemctl status"] }
48
48
 
49
- resolved: { allowPatterns: ["sudo systemctl status"] } ← cae al nivel global
49
+ resolved: { allowPatterns: ["sudo systemctl status"] } ← recae en global
50
50
  ```
51
51
 
52
- **`customPoliciesPath`** gana el primer ámbito que lo defina.
52
+ **`customPoliciesPath`** - el primer ámbito que lo define gana.
53
53
 
54
- **`llm`** gana el primer ámbito que lo defina.
54
+ **`llm`** - el primer ámbito que lo define gana.
55
55
 
56
56
  ---
57
57
 
@@ -112,17 +112,17 @@ Tipo: `Record<string, Record<string, unknown>>`
112
112
 
113
113
  Anulaciones de parámetros por política. La clave externa es el nombre de la política; las claves internas son específicas de cada política. Cada política documenta sus parámetros disponibles en [Políticas integradas](/es/built-in-policies).
114
114
 
115
- Si una política tiene parámetros pero no los especificas, se usan los valores predeterminados integrados de la política. Los usuarios que no configuren `policyParams` en absoluto obtendrán un comportamiento idéntico al de las versiones anteriores.
115
+ Si una política tiene parámetros pero no los especificas, se utilizan los valores predeterminados integrados de la política. Los usuarios que no configuren `policyParams` en absoluto obtendrán un comportamiento idéntico al de versiones anteriores.
116
116
 
117
- Las claves desconocidas dentro del bloque de parámetros de una política se ignoran silenciosamente en el momento de disparar el hook, pero se marcan como advertencias cuando ejecutas `failproofai policies`.
117
+ Las claves desconocidas dentro del bloque de parámetros de una política se ignoran silenciosamente al momento de ejecutar el hook, pero se marcan como advertencias cuando ejecutas `failproofai policies`.
118
118
 
119
119
  #### `hint` (transversal)
120
120
 
121
121
  Tipo: `string` (opcional)
122
122
 
123
- Un mensaje que se añade al motivo cuando una política devuelve `deny` o `instruct`. Úsalo para dar a Claude orientación accionable sin modificar la política en sí.
123
+ Un mensaje que se añade al motivo cuando una política devuelve `deny` o `instruct`. Úsalo para dar a Claude orientación práctica sin modificar la política en sí.
124
124
 
125
- Funciona con cualquier tipo de política: integrada, personalizada (`custom/`), convención de proyecto (`.failproofai-project/`) o convención de usuario (`.failproofai-user/`).
125
+ Funciona con cualquier tipo de política: integradas, personalizadas (`custom/`), convenciones de proyecto (`.failproofai-project/`) o convenciones de usuario (`.failproofai-user/`).
126
126
 
127
127
  ```json
128
128
  {
@@ -141,7 +141,7 @@ Funciona con cualquier tipo de política: integrada, personalizada (`custom/`),
141
141
  }
142
142
  ```
143
143
 
144
- Cuando block-force-push deniega, Claude ve: *"Force-pushing is blocked. Try creating a fresh branch instead."*
144
+ Cuando `block-force-push` deniega, Claude ve: *"Force-pushing is blocked. Try creating a fresh branch instead."*
145
145
 
146
146
  Los valores que no sean cadenas de texto y las cadenas vacías se ignoran silenciosamente. Si `hint` no está definido, el comportamiento no cambia (compatible con versiones anteriores).
147
147
 
@@ -149,24 +149,24 @@ Los valores que no sean cadenas de texto y las cadenas vacías se ignoran silenc
149
149
 
150
150
  Tipo: `string` (ruta absoluta)
151
151
 
152
- Ruta a un archivo JavaScript que contiene políticas de hook personalizadas. Este valor lo establece automáticamente `failproofai policies --install --custom <path>` (la ruta se resuelve a absoluta antes de almacenarse).
152
+ Ruta a un archivo JavaScript que contiene políticas de hook personalizadas. Se establece automáticamente mediante `failproofai policies --install --custom <path>` (la ruta se resuelve como absoluta antes de guardarse).
153
153
 
154
- El archivo se carga desde cero en cada evento de hook; no hay caché. Consulta [Políticas personalizadas](/es/custom-policies) para ver los detalles de creación.
154
+ El archivo se carga de nuevo en cada evento de hook, sin ningún tipo de caché. Consulta [Políticas personalizadas](/es/custom-policies) para más detalles sobre cómo crearlas.
155
155
 
156
- ### Políticas basadas en convención
156
+ ### Políticas basadas en convenciones
157
157
 
158
158
  Además del `customPoliciesPath` explícito, failproofai descubre y carga automáticamente archivos de políticas desde directorios `.failproofai/policies/`:
159
159
 
160
160
  | Nivel | Directorio | Ámbito |
161
161
  |-------|-----------|--------|
162
- | Proyecto | `.failproofai/policies/` | Compartido con el equipo a través del control de versiones |
162
+ | Proyecto | `.failproofai/policies/` | Compartido con el equipo mediante control de versiones |
163
163
  | Usuario | `~/.failproofai/policies/` | Personal, se aplica a todos los proyectos |
164
164
 
165
165
  **Coincidencia de archivos:** Solo se cargan los archivos que coincidan con `*policies.{js,mjs,ts}` (por ejemplo, `security-policies.mjs`, `workflow-policies.js`). Los demás archivos del directorio se ignoran.
166
166
 
167
- **Sin configuración necesaria:** Las políticas de convención no requieren entradas en `policies-config.json`. Simplemente coloca los archivos en el directorio y se detectarán en el siguiente evento de hook.
167
+ **Sin configuración necesaria:** Las políticas de convención no requieren entradas en `policies-config.json`. Simplemente coloca los archivos en el directorio y se detectarán en el próximo evento de hook.
168
168
 
169
- **Carga por unión:** Se analizan tanto el directorio de convención del proyecto como el del usuario. Todos los archivos coincidentes de ambos niveles se cargan (a diferencia de `customPoliciesPath`, que usa el criterio de primer ámbito que gana).
169
+ **Carga por unión:** Se analizan tanto los directorios de convención del proyecto como los del usuario. Se cargan todos los archivos coincidentes de ambos niveles (a diferencia de `customPoliciesPath`, que utiliza el primero que gana por ámbito).
170
170
 
171
171
  Consulta [Políticas personalizadas](/es/custom-policies) para más detalles y ejemplos.
172
172
 
@@ -174,7 +174,7 @@ Consulta [Políticas personalizadas](/es/custom-policies) para más detalles y e
174
174
 
175
175
  Tipo: `object` (opcional)
176
176
 
177
- Configuración del cliente LLM para políticas que realizan llamadas a IA. No es necesario para la mayoría de las configuraciones.
177
+ Configuración del cliente LLM para políticas que realizan llamadas a IA. No es necesaria para la mayoría de las configuraciones.
178
178
 
179
179
  ```json
180
180
  {
@@ -189,12 +189,12 @@ Configuración del cliente LLM para políticas que realizan llamadas a IA. No es
189
189
 
190
190
  ## Gestión de la configuración desde la CLI
191
191
 
192
- Los comandos `policies --install` y `policies --uninstall` escriben en el settings.json de Claude Code (los puntos de entrada del hook), mientras que policies-config.json es el archivo que gestionas directamente. Los dos son independientes:
192
+ Los comandos `policies --install` y `policies --uninstall` escriben en el `settings.json` de Claude Code (los puntos de entrada del hook), mientras que `policies-config.json` es el archivo que gestionas directamente. Ambos son independientes:
193
193
 
194
- - **`settings.json`** le indica a Claude Code que llame a `failproofai --hook <event>` en cada uso de herramienta
195
- - **`policies-config.json`** le indica a failproofai qué políticas evaluar y con qué parámetros
194
+ - **`settings.json`** - indica a Claude Code que llame a `failproofai --hook <event>` en cada uso de herramienta
195
+ - **`policies-config.json`** - indica a failproofai qué políticas evaluar y con qué parámetros
196
196
 
197
- Puedes editar `policies-config.json` directamente en cualquier momento; los cambios surten efecto de inmediato en el siguiente evento de hook sin necesidad de reiniciar.
197
+ Puedes editar `policies-config.json` directamente en cualquier momento; los cambios surten efecto de inmediato en el próximo evento de hook, sin necesidad de reiniciar.
198
198
 
199
199
  ---
200
200
 
@@ -1,10 +1,10 @@
1
1
  ---
2
2
  title: Políticas Personalizadas
3
- description: "Escribe tus propias políticas en JavaScript: aplica convenciones, previene derivas, detecta fallos e intégrate con sistemas externos"
3
+ description: "Escribe tus propias políticas en JavaScript: aplica convenciones, previene la deriva, detecta fallos e integra con sistemas externos"
4
4
  icon: code
5
5
  ---
6
6
 
7
- Las políticas personalizadas te permiten escribir reglas para cualquier comportamiento del agente: aplicar convenciones del proyecto, prevenir derivas, controlar operaciones destructivas, detectar agentes bloqueados o integrarte con Slack, flujos de aprobación y más. Utilizan el mismo sistema de eventos de hook y las mismas decisiones `allow`, `deny`, `instruct` que las políticas integradas.
7
+ Las políticas personalizadas te permiten escribir reglas para cualquier comportamiento del agente: aplicar convenciones del proyecto, prevenir la deriva, bloquear operaciones destructivas, detectar agentes atascados o integrarte con Slack, flujos de aprobación y más. Utilizan el mismo sistema de eventos de hook y las decisiones `allow`, `deny`, `instruct` que las políticas integradas.
8
8
 
9
9
  ---
10
10
 
@@ -29,7 +29,7 @@ customPolicies.add({
29
29
  });
30
30
  ```
31
31
 
32
- Instálala:
32
+ Instálalo:
33
33
 
34
34
  ```bash
35
35
  failproofai policies --install --custom ./my-policies.js
@@ -39,9 +39,9 @@ failproofai policies --install --custom ./my-policies.js
39
39
 
40
40
  ## Dos formas de cargar políticas personalizadas
41
41
 
42
- ### Opción 1: Basada en convención (recomendada)
42
+ ### Opción 1: Basada en convenciones (recomendada)
43
43
 
44
- Coloca archivos `*policies.{js,mjs,ts}` en `.failproofai/policies/` y se cargarán automáticamente, sin necesidad de flags ni cambios de configuración. Funciona como los git hooks: coloca el archivo y listo.
44
+ Coloca archivos `*policies.{js,mjs,ts}` en `.failproofai/policies/` y se cargarán automáticamente, sin necesidad de flags ni cambios de configuración. Funciona como los git hooks: deposita un archivo y ya está.
45
45
 
46
46
  ```
47
47
  # Nivel de proyecto — incluido en git, compartido con el equipo
@@ -53,14 +53,14 @@ Coloca archivos `*policies.{js,mjs,ts}` en `.failproofai/policies/` y se cargar
53
53
  ```
54
54
 
55
55
  **Cómo funciona:**
56
- - Se analizan tanto el directorio del proyecto como el del usuario (unión — no el primero que coincida por alcance)
57
- - Los archivos se cargan alfabéticamente dentro de cada directorio. Usa prefijos `01-`, `02-` para controlar el orden
58
- - Solo se cargan los archivos que coincidan con `*policies.{js,mjs,ts}`; el resto se ignoran
56
+ - Se analizan tanto el directorio del proyecto como el del usuario (unión — no gana el primero en ámbito)
57
+ - Los archivos se cargan en orden alfabético dentro de cada directorio. Usa el prefijo `01-`, `02-` para controlar el orden
58
+ - Solo se cargan los archivos que coincidan con `*policies.{js,mjs,ts}`; los demás se ignoran
59
59
  - Cada archivo se carga de forma independiente (fail-open por archivo)
60
60
  - Funciona junto con `--custom` explícito y las políticas integradas
61
61
 
62
62
  <Tip>
63
- Las políticas por convención son la forma más sencilla de compartir políticas en un equipo. Incluye `.failproofai/policies/` en git y todos los miembros del equipo las recibirán automáticamente.
63
+ Las políticas por convención son la forma más sencilla de compartir políticas en un equipo. Incluye `.failproofai/policies/` en git y todos los miembros del equipo las obtendrán automáticamente.
64
64
  </Tip>
65
65
 
66
66
  ### Opción 2: Ruta de archivo explícita
@@ -76,15 +76,15 @@ failproofai policies --install --custom ./new-policies.js
76
76
  failproofai policies --uninstall --custom
77
77
  ```
78
78
 
79
- La ruta absoluta resuelta se almacena en `policies-config.json` como `customPoliciesPath`. El archivo se carga de nuevo en cada evento de hook; no hay caché entre eventos.
79
+ La ruta absoluta resuelta se almacena en `policies-config.json` como `customPoliciesPath`. El archivo se carga de nuevo en cada evento de hook no hay caché entre eventos.
80
80
 
81
- ### Usar ambas juntas
81
+ ### Usando ambas formas juntas
82
82
 
83
83
  Las políticas por convención y el archivo `--custom` explícito pueden coexistir. Orden de carga:
84
84
 
85
85
  1. Archivo explícito `customPoliciesPath` (si está configurado)
86
- 2. Archivos de convención del proyecto (`{cwd}/.failproofai/policies/`, alfabético)
87
- 3. Archivos de convención del usuario (`~/.failproofai/policies/`, alfabético)
86
+ 2. Archivos de convención del proyecto (`{cwd}/.failproofai/policies/`, en orden alfabético)
87
+ 3. Archivos de convención del usuario (`~/.failproofai/policies/`, en orden alfabético)
88
88
 
89
89
  ---
90
90
 
@@ -98,13 +98,13 @@ import { customPolicies, allow, deny, instruct } from "failproofai";
98
98
 
99
99
  ### `customPolicies.add(hook)`
100
100
 
101
- Registra una política. Llámalo las veces que necesites para definir múltiples políticas en el mismo archivo.
101
+ Registra una política. Llámalo tantas veces como sea necesario para múltiples políticas en el mismo archivo.
102
102
 
103
103
  ```ts
104
104
  customPolicies.add({
105
105
  name: string; // requerido - identificador único
106
106
  description?: string; // se muestra en la salida de `failproofai policies`
107
- match?: { events?: HookEventType[] }; // filtra por tipo de evento; omítelo para coincidir con todos
107
+ match?: { events?: HookEventType[] }; // filtra por tipo de evento; omite para coincidir con todos
108
108
  fn: (ctx: PolicyContext) => PolicyResult | Promise<PolicyResult>;
109
109
  });
110
110
  ```
@@ -113,22 +113,21 @@ customPolicies.add({
113
113
 
114
114
  | Función | Efecto | Cuándo usarla |
115
115
  |----------|--------|----------|
116
- | `allow()` | Permite la operación silenciosamente | La acción es segura y no se necesita mensaje |
116
+ | `allow()` | Permite la operación en silencio | La acción es segura, no se necesita mensaje |
117
117
  | `deny(message)` | Bloquea la operación | El agente no debería realizar esta acción |
118
118
  | `instruct(message)` | Añade contexto sin bloquear | Proporciona contexto adicional al agente para mantenerlo en curso |
119
119
 
120
- `deny(message)` — el mensaje aparece para Claude con el prefijo `"Blocked by failproofai:"`. Un solo `deny` cortocircuita toda evaluación posterior.
120
+ `deny(message)` — el mensaje aparece ante Claude con el prefijo `"Blocked by failproofai:"`. Un único `deny` cortocircuita toda evaluación posterior.
121
121
 
122
122
  `instruct(message)` — el mensaje se añade al contexto de Claude para la llamada de herramienta actual. Todos los mensajes `instruct` se acumulan y se entregan juntos.
123
123
 
124
124
  <Tip>
125
- Puedes añadir orientación adicional a cualquier mensaje `deny` o `instruct` incluyendo un campo `hint` en `policyParams`, sin necesidad de cambiar el código. Esto funciona también para políticas personalizadas (`custom/`), de convención de proyecto (`.failproofai-project/`) y de convención de usuario (`.failproofai-user/`). Consulta [Configuración → hint](/es/configuration#hint-cross-cutting) para más detalles.
125
+ Puedes añadir orientación adicional a cualquier mensaje `deny` o `instruct` agregando un campo `hint` en `policyParams`, sin necesidad de cambiar el código. Esto también funciona para políticas personalizadas (`custom/`), de convención de proyecto (`.failproofai-project/`) y de convención de usuario (`.failproofai-user/`). Consulta [Configuración → hint](/es/configuration#hint-cross-cutting) para más detalles.
126
126
  </Tip>
127
127
 
128
128
  ### Mensajes informativos en allow
129
129
 
130
-
131
- `allow(message)` permite la operación **y** envía un mensaje informativo a Claude. El mensaje se entrega como `additionalContext` en la respuesta stdout del manejador de hooks — el mismo mecanismo que usa `instruct`, pero con una semántica diferente: es una actualización de estado, no una advertencia.
130
+ `allow(message)` permite la operación **y** envía un mensaje informativo a Claude. El mensaje se entrega como `additionalContext` en la respuesta stdout del manejador de hooks — el mismo mecanismo que usa `instruct`, pero semánticamente distinto: es una actualización de estado, no una advertencia.
132
131
 
133
132
  | Función | Efecto | Cuándo usarla |
134
133
  |----------|--------|----------|
@@ -136,8 +135,8 @@ Puedes añadir orientación adicional a cualquier mensaje `deny` o `instruct` in
136
135
 
137
136
  Casos de uso:
138
137
  - **Confirmaciones de estado:** `allow("All CI checks passed.")` — le indica a Claude que todo está en orden
139
- - **Explicaciones de fail-open:** `allow("GitHub CLI not installed, skipping CI check.")` — le dice a Claude por qué se omitió una verificación para que tenga contexto completo
140
- - **Los mensajes se acumulan:** si varias políticas devuelven `allow(message)`, todos los mensajes se unen con saltos de línea y se entregan juntos
138
+ - **Explicaciones de fail-open:** `allow("GitHub CLI not installed, skipping CI check.")` — le indica a Claude por qué se omitió una verificación para que tenga contexto completo
139
+ - **Acumulación de múltiples mensajes:** si varias políticas devuelven `allow(message)`, todos los mensajes se unen con saltos de línea y se entregan juntos
141
140
 
142
141
  ```js
143
142
  customPolicies.add({
@@ -163,8 +162,8 @@ customPolicies.add({
163
162
  | `eventType` | `string` | `"PreToolUse"`, `"PostToolUse"`, `"Notification"`, `"Stop"` |
164
163
  | `toolName` | `string \| undefined` | La herramienta que se está invocando (p. ej. `"Bash"`, `"Write"`, `"Read"`) |
165
164
  | `toolInput` | `Record<string, unknown> \| undefined` | Los parámetros de entrada de la herramienta |
166
- | `payload` | `Record<string, unknown>` | Payload completo del evento raw de Claude Code |
167
- | `session` | `SessionMetadata \| undefined` | Contexto de sesión (ver más abajo) |
165
+ | `payload` | `Record<string, unknown>` | Payload completo del evento sin procesar, proveniente de Claude Code |
166
+ | `session` | `SessionMetadata \| undefined` | Contexto de la sesión (ver más abajo) |
168
167
 
169
168
  ### Campos de `SessionMetadata`
170
169
 
@@ -179,7 +178,7 @@ customPolicies.add({
179
178
  | Evento | Cuándo se dispara | Contenido de `toolInput` |
180
179
  |-------|--------------|----------------------|
181
180
  | `PreToolUse` | Antes de que Claude ejecute una herramienta | La entrada de la herramienta (p. ej. `{ command: "..." }` para Bash) |
182
- | `PostToolUse` | Después de que una herramienta completa | La entrada de la herramienta + `tool_result` (la salida) |
181
+ | `PostToolUse` | Después de que una herramienta completa su ejecución | La entrada de la herramienta + `tool_result` (la salida) |
183
182
  | `Notification` | Cuando Claude envía una notificación | `{ message: "...", notification_type: "idle" \| "permission_prompt" \| ... }` — los hooks siempre deben devolver `allow()`, no pueden bloquear notificaciones |
184
183
  | `Stop` | Cuando la sesión de Claude finaliza | Vacío |
185
184
 
@@ -191,8 +190,8 @@ Las políticas se evalúan en este orden:
191
190
 
192
191
  1. Políticas integradas (en orden de definición)
193
192
  2. Políticas personalizadas explícitas de `customPoliciesPath` (en orden de `.add()`)
194
- 3. Políticas de convención del proyecto `.failproofai/policies/` (archivos en orden alfabético, orden de `.add()` dentro de cada archivo)
195
- 4. Políticas de convención del usuario `~/.failproofai/policies/` (archivos en orden alfabético, orden de `.add()` dentro de cada archivo)
193
+ 3. Políticas de convención del proyecto en `.failproofai/policies/` (archivos en orden alfabético, orden de `.add()` dentro de cada uno)
194
+ 4. Políticas de convención del usuario en `~/.failproofai/policies/` (archivos en orden alfabético, orden de `.add()` dentro de cada uno)
196
195
 
197
196
  <Note>
198
197
  El primer `deny` cortocircuita todas las políticas siguientes. Todos los mensajes `instruct` se acumulan y se entregan juntos.
@@ -219,7 +218,7 @@ customPolicies.add({
219
218
  });
220
219
  ```
221
220
 
222
- Se resuelven todas las importaciones relativas accesibles desde el archivo de entrada. Esto se implementa reescribiendo las importaciones `from "failproofai"` a la ruta real de dist y creando archivos `.mjs` temporales para garantizar la compatibilidad con ESM.
221
+ Se resuelven todas las importaciones relativas alcanzables desde el archivo de entrada. Esto se implementa reescribiendo las importaciones `from "failproofai"` a la ruta real de dist y creando archivos `.mjs` temporales para garantizar la compatibilidad con ESM.
223
222
 
224
223
  ---
225
224
 
@@ -232,33 +231,33 @@ customPolicies.add({
232
231
  name: "require-summary-on-stop",
233
232
  match: { events: ["Stop"] },
234
233
  fn: async (ctx) => {
235
- // Solo se dispara cuando la sesión finaliza
236
- // ctx.session.transcriptPath contiene el log completo de la sesión
234
+ // Solo se dispara cuando la sesión termina
235
+ // ctx.session.transcriptPath contiene el registro completo de la sesión
237
236
  return allow();
238
237
  },
239
238
  });
240
239
  ```
241
240
 
242
- Omite `match` por completo para que se dispare en todos los tipos de eventos.
241
+ Omite `match` por completo para disparar en cada tipo de evento.
243
242
 
244
243
  ---
245
244
 
246
245
  ## Manejo de errores y modos de fallo
247
246
 
248
- Las políticas personalizadas son **fail-open**: los errores nunca bloquean las políticas integradas ni causan un crash en el manejador de hooks.
247
+ Las políticas personalizadas son **fail-open**: los errores nunca bloquean las políticas integradas ni hacen fallar el manejador de hooks.
249
248
 
250
249
  | Fallo | Comportamiento |
251
250
  |---------|----------|
252
- | `customPoliciesPath` no configurado | No se ejecutan políticas personalizadas explícitas; las políticas por convención y las integradas continúan con normalidad |
253
- | Archivo no encontrado | Se registra una advertencia en `~/.failproofai/hook.log`; las políticas integradas continúan |
251
+ | `customPoliciesPath` no configurado | No se ejecutan políticas personalizadas explícitas; las políticas de convención y las integradas continúan con normalidad |
252
+ | Archivo no encontrado | Se registra una advertencia en `~/.failproofai/hook.log`; las integradas continúan |
254
253
  | Error de sintaxis/importación (explícito) | Error registrado en `~/.failproofai/hook.log`; se omiten las políticas personalizadas explícitas |
255
- | Error de sintaxis/importación (convención) | Error registrado; ese archivo se omite, los demás archivos de convención siguen cargándose |
254
+ | Error de sintaxis/importación (convención) | Error registrado; ese archivo se omite, los demás archivos de convención se cargan igualmente |
256
255
  | `fn` lanza un error en tiempo de ejecución | Error registrado; ese hook se trata como `allow`; los demás hooks continúan |
257
- | `fn` tarda más de 10 segundos | Timeout registrado; se trata como `allow` |
258
- | Directorio de convención inexistente | No se ejecutan políticas de convención; sin error |
256
+ | `fn` tarda más de 10 segundos | Se registra el timeout; se trata como `allow` |
257
+ | Directorio de convención faltante | No se ejecutan políticas de convención; sin error |
259
258
 
260
259
  <Tip>
261
- Para depurar errores en políticas personalizadas, observa el archivo de log:
260
+ Para depurar errores en políticas personalizadas, monitorea el archivo de log:
262
261
 
263
262
  ```bash
264
263
  tail -f ~/.failproofai/hook.log
@@ -273,7 +272,7 @@ tail -f ~/.failproofai/hook.log
273
272
  // my-policies.js
274
273
  import { customPolicies, allow, deny, instruct } from "failproofai";
275
274
 
276
- // Prevent agent from writing to secrets/ directory
275
+ // Evitar que el agente escriba en el directorio secrets/
277
276
  customPolicies.add({
278
277
  name: "block-secrets-dir",
279
278
  description: "Prevent agent from writing to secrets/ directory",
@@ -286,7 +285,7 @@ customPolicies.add({
286
285
  },
287
286
  });
288
287
 
289
- // Keep the agent on track: verify tests before committing
288
+ // Mantener al agente en curso: verificar tests antes de hacer commit
290
289
  customPolicies.add({
291
290
  name: "remind-test-before-commit",
292
291
  description: "Keep the agent on track: verify tests pass before committing",
@@ -301,7 +300,7 @@ customPolicies.add({
301
300
  },
302
301
  });
303
302
 
304
- // Prevent unplanned dependency changes during freeze
303
+ // Prevenir cambios de dependencias no planificados durante el período de congelamiento
305
304
  customPolicies.add({
306
305
  name: "dependency-freeze",
307
306
  description: "Prevent unplanned dependency changes during freeze period",
@@ -324,22 +323,22 @@ export { customPolicies };
324
323
 
325
324
  ## Ejemplos
326
325
 
327
- El directorio `examples/` contiene archivos de políticas listos para ejecutar:
326
+ El directorio `examples/` contiene archivos de políticas listos para usar:
328
327
 
329
328
  | Archivo | Contenido |
330
329
  |------|----------|
331
- | `examples/policies-basic.js` | Cinco políticas de inicio que cubren los modos de fallo más comunes de los agentes |
332
- | `examples/policies-advanced/index.js` | Patrones avanzados: importaciones transitivas, llamadas asíncronas, limpieza de salidas y hooks de fin de sesión |
333
- | `examples/convention-policies/security-policies.mjs` | Políticas de seguridad por convención (bloquea escrituras en .env, previene reescritura del historial de git) |
334
- | `examples/convention-policies/workflow-policies.mjs` | Políticas de flujo de trabajo por convención (recordatorios de tests, auditoría de escrituras en archivos) |
330
+ | `examples/policies-basic.js` | Cinco políticas iniciales que cubren los modos de fallo más comunes del agente |
331
+ | `examples/policies-advanced/index.js` | Patrones avanzados: importaciones transitivas, llamadas asíncronas, limpieza de salida y hooks al final de sesión |
332
+ | `examples/convention-policies/security-policies.mjs` | Políticas de seguridad basadas en convenciones (bloquear escrituras en .env, prevenir la reescritura del historial de git) |
333
+ | `examples/convention-policies/workflow-policies.mjs` | Políticas de flujo de trabajo basadas en convenciones (recordatorios de tests, auditoría de escrituras en archivos) |
335
334
 
336
- ### Usar los ejemplos con archivo explícito
335
+ ### Uso de los ejemplos con archivo explícito
337
336
 
338
337
  ```bash
339
338
  failproofai policies --install --custom ./examples/policies-basic.js
340
339
  ```
341
340
 
342
- ### Usar los ejemplos basados en convención
341
+ ### Uso de los ejemplos basados en convenciones
343
342
 
344
343
  ```bash
345
344
  # Copiar al nivel del proyecto
@@ -351,4 +350,4 @@ mkdir -p ~/.failproofai/policies
351
350
  cp examples/convention-policies/*.mjs ~/.failproofai/policies/
352
351
  ```
353
352
 
354
- No se necesita ningún comando de instalación — los archivos se detectan automáticamente en el siguiente evento de hook.
353
+ No se necesita ningún comando de instalación — los archivos se detectan automáticamente en el próximo evento de hook.
@@ -242,6 +242,60 @@ Every team member who has failproofai installed will automatically pick up these
242
242
 
243
243
  ---
244
244
 
245
+ ## Build an org-wide quality standard with convention policies
246
+
247
+ The most impactful setup: commit `.failproofai/policies/` to your repo with policies tailored to your project. Every team member gets them automatically — no install commands, no config changes.
248
+
249
+ <Steps>
250
+ <Step title="Create the directory and add policies">
251
+ ```bash
252
+ mkdir -p .failproofai/policies
253
+ ```
254
+
255
+ ```js
256
+ // .failproofai/policies/team-policies.mjs
257
+ import { customPolicies, allow, deny, instruct } from "failproofai";
258
+
259
+ // Enforce your team's preferred package manager
260
+ // (or enable the built-in prefer-package-manager policy instead)
261
+ customPolicies.add({
262
+ name: "enforce-bun",
263
+ match: { events: ["PreToolUse"] },
264
+ fn: async (ctx) => {
265
+ if (ctx.toolName !== "Bash") return allow();
266
+ const cmd = String(ctx.toolInput?.command ?? "");
267
+ if (/\bnpm\b/.test(cmd)) return deny("Use bun instead of npm.");
268
+ return allow();
269
+ },
270
+ });
271
+
272
+ // Remind the agent to run tests before committing
273
+ customPolicies.add({
274
+ name: "test-before-commit",
275
+ match: { events: ["PreToolUse"] },
276
+ fn: async (ctx) => {
277
+ if (ctx.toolName !== "Bash") return allow();
278
+ if (/git\s+commit/.test(ctx.toolInput?.command ?? "")) {
279
+ return instruct("Run tests before committing.");
280
+ }
281
+ return allow();
282
+ },
283
+ });
284
+ ```
285
+ </Step>
286
+ <Step title="Commit to git">
287
+ ```bash
288
+ git add .failproofai/policies/
289
+ git commit -m "Add team quality policies"
290
+ ```
291
+ </Step>
292
+ <Step title="Keep improving">
293
+ As your team hits new failure modes, add policies and push. Everyone gets the update on their next `git pull`. These policies become a living quality standard that grows with your team.
294
+ </Step>
295
+ </Steps>
296
+
297
+ ---
298
+
245
299
  ## More examples
246
300
 
247
301
  The [`examples/`](https://github.com/exospherehost/failproofai/tree/main/examples) directory in the repo contains: