failproofai 0.0.5-beta.0 → 0.0.6-beta.0
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.
- package/.next/standalone/.failproofai/policies/workflow-policies.mjs +2 -1
- package/.next/standalone/.next/BUILD_ID +1 -1
- package/.next/standalone/.next/build-manifest.json +3 -3
- package/.next/standalone/.next/prerender-manifest.json +3 -3
- package/.next/standalone/.next/required-server-files.json +1 -1
- package/.next/standalone/.next/server/app/_global-error/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_global-error.html +1 -1
- package/.next/standalone/.next/server/app/_global-error.rsc +7 -7
- package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +7 -7
- package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +3 -3
- package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +3 -3
- package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_not-found.html +2 -2
- package/.next/standalone/.next/server/app/_not-found.rsc +15 -15
- package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +15 -15
- package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +4 -4
- package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +10 -10
- package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +3 -3
- package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/index.html +1 -1
- package/.next/standalone/.next/server/app/index.rsc +15 -15
- package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +15 -15
- package/.next/standalone/.next/server/app/index.segments/_head.segment.rsc +4 -4
- package/.next/standalone/.next/server/app/index.segments/_index.segment.rsc +10 -10
- package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/policies/page/server-reference-manifest.json +8 -8
- package/.next/standalone/.next/server/app/policies/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/policies/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/project/[name]/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/project/[name]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/project/[name]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/react-loadable-manifest.json +2 -2
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/server-reference-manifest.json +2 -2
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/projects/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/projects/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/projects/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0g72weg._.js +1 -1
- package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_0z7w.hh._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0r6vvp5._.js → [root-of-the-server]__0.~fd7s._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__092s1ta._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__09icjsf._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0z5dd-f._.js → [root-of-the-server]__0a.nuas._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0g.lg8b._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0h..k-e._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0okos0k._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0w6l33k._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__11pa2ra._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__12t-wym._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/_10lm7or._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/app_global-error_tsx_0xerkr6._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_policies_hooks-client_tsx_0q-m0y-._.js +1 -1
- package/.next/standalone/.next/server/middleware-build-manifest.js +3 -3
- package/.next/standalone/.next/server/pages/404.html +2 -2
- package/.next/standalone/.next/server/pages/500.html +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.json +9 -9
- package/.next/standalone/.next/static/chunks/{0j_ivegn3i5wt.js → 0.z51twd.0l5z.js} +1 -1
- package/.next/standalone/.next/static/chunks/{04fpsjft~cje..js → 0hctoh28rg838.js} +1 -1
- package/.next/standalone/.next/static/chunks/{0.io32u7gjgsb.js → 0hplx-8c-4vpv.js} +1 -1
- package/.next/standalone/.next/static/chunks/{0yf_mmdukq6up.js → 0maq.q1t.ri85.js} +2 -2
- package/.next/standalone/.next/static/chunks/{0x8vagatq36_7.js → 0teq8wdh3po1n.js} +1 -1
- package/.next/standalone/.next/static/chunks/{04mtv9jnqknn3.js → 0uc0um_uz51m_.js} +1 -1
- package/.next/standalone/.next/static/chunks/{0h4qcn40dunn7.js → 0ul6fk-z.6k-0.js} +1 -1
- package/.next/standalone/.next/static/chunks/{0kvldut6ndzyz.js → 0w9lwqy0-v1dk.js} +1 -1
- package/.next/standalone/CHANGELOG.md +9 -1
- package/.next/standalone/README.md +2 -2
- package/.next/standalone/dist/cli.mjs +19 -2
- package/.next/standalone/docs/ar/architecture.mdx +66 -65
- package/.next/standalone/docs/ar/configuration.mdx +42 -42
- package/.next/standalone/docs/ar/custom-policies.mdx +63 -68
- package/.next/standalone/docs/architecture.mdx +2 -2
- package/.next/standalone/docs/configuration.mdx +1 -1
- package/.next/standalone/docs/custom-policies.mdx +2 -6
- package/.next/standalone/docs/de/architecture.mdx +92 -92
- package/.next/standalone/docs/de/configuration.mdx +35 -35
- package/.next/standalone/docs/de/custom-policies.mdx +50 -54
- package/.next/standalone/docs/es/architecture.mdx +73 -73
- package/.next/standalone/docs/es/configuration.mdx +25 -25
- package/.next/standalone/docs/es/custom-policies.mdx +49 -53
- package/.next/standalone/docs/fr/architecture.mdx +55 -55
- package/.next/standalone/docs/fr/configuration.mdx +26 -26
- package/.next/standalone/docs/fr/custom-policies.mdx +42 -46
- package/.next/standalone/docs/he/architecture.mdx +67 -67
- package/.next/standalone/docs/he/configuration.mdx +53 -52
- package/.next/standalone/docs/he/custom-policies.mdx +73 -77
- package/.next/standalone/docs/hi/architecture.mdx +107 -107
- package/.next/standalone/docs/hi/configuration.mdx +39 -39
- package/.next/standalone/docs/hi/custom-policies.mdx +77 -81
- package/.next/standalone/docs/i18n/README.ar.md +66 -66
- package/.next/standalone/docs/i18n/README.de.md +40 -40
- package/.next/standalone/docs/i18n/README.es.md +40 -40
- package/.next/standalone/docs/i18n/README.fr.md +44 -44
- package/.next/standalone/docs/i18n/README.he.md +67 -67
- package/.next/standalone/docs/i18n/README.hi.md +71 -71
- package/.next/standalone/docs/i18n/README.it.md +63 -63
- package/.next/standalone/docs/i18n/README.ja.md +55 -55
- package/.next/standalone/docs/i18n/README.ko.md +59 -59
- package/.next/standalone/docs/i18n/README.pt-br.md +45 -45
- package/.next/standalone/docs/i18n/README.ru.md +71 -71
- package/.next/standalone/docs/i18n/README.tr.md +76 -76
- package/.next/standalone/docs/i18n/README.vi.md +71 -71
- package/.next/standalone/docs/i18n/README.zh.md +53 -53
- package/.next/standalone/docs/it/architecture.mdx +55 -54
- package/.next/standalone/docs/it/configuration.mdx +45 -46
- package/.next/standalone/docs/it/custom-policies.mdx +77 -82
- package/.next/standalone/docs/ja/architecture.mdx +93 -93
- package/.next/standalone/docs/ja/configuration.mdx +48 -48
- package/.next/standalone/docs/ja/custom-policies.mdx +63 -67
- package/.next/standalone/docs/ko/architecture.mdx +66 -66
- package/.next/standalone/docs/ko/configuration.mdx +36 -36
- package/.next/standalone/docs/ko/custom-policies.mdx +73 -77
- package/.next/standalone/docs/pt-br/architecture.mdx +55 -55
- package/.next/standalone/docs/pt-br/configuration.mdx +36 -36
- package/.next/standalone/docs/pt-br/custom-policies.mdx +62 -66
- package/.next/standalone/docs/ru/architecture.mdx +59 -60
- package/.next/standalone/docs/ru/configuration.mdx +52 -53
- package/.next/standalone/docs/ru/custom-policies.mdx +70 -74
- package/.next/standalone/docs/tr/architecture.mdx +124 -124
- package/.next/standalone/docs/tr/configuration.mdx +46 -47
- package/.next/standalone/docs/tr/custom-policies.mdx +75 -78
- package/.next/standalone/docs/vi/architecture.mdx +65 -64
- package/.next/standalone/docs/vi/configuration.mdx +42 -42
- package/.next/standalone/docs/vi/custom-policies.mdx +68 -72
- package/.next/standalone/docs/zh/architecture.mdx +67 -67
- package/.next/standalone/docs/zh/configuration.mdx +35 -35
- package/.next/standalone/docs/zh/custom-policies.mdx +54 -58
- package/.next/standalone/package.json +1 -1
- package/.next/standalone/server.js +1 -1
- package/.next/standalone/src/hooks/builtin-policies.ts +30 -0
- package/README.md +2 -2
- package/dist/cli.mjs +19 -2
- package/package.json +1 -1
- package/src/hooks/builtin-policies.ts +30 -0
- /package/.next/standalone/.next/static/{ICeMHZ-8ZR7HY5GLm7oSJ → 8mygPGI5bzrtWK36ZYO59}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{ICeMHZ-8ZR7HY5GLm7oSJ → 8mygPGI5bzrtWK36ZYO59}/_clientMiddlewareManifest.js +0 -0
- /package/.next/standalone/.next/static/{ICeMHZ-8ZR7HY5GLm7oSJ → 8mygPGI5bzrtWK36ZYO59}/_ssgManifest.js +0 -0
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
---
|
|
2
|
+
|
|
2
3
|
---
|
|
3
4
|
title: Architettura
|
|
4
|
-
description: "Come il gestore
|
|
5
|
+
description: "Come funzionano internamente il gestore hook, il caricamento della config e la valutazione delle policy"
|
|
5
6
|
icon: sitemap
|
|
6
7
|
---
|
|
7
8
|
|
|
8
|
-
Questo documento spiega come failproofai funziona internamente: come il sistema di hook intercetta le chiamate agli strumenti dell'agente, come viene caricata e unita la configurazione, come vengono valutate le
|
|
9
|
+
Questo documento spiega come failproofai funziona internamente: come il sistema di hook intercetta le chiamate agli strumenti dell'agente, come viene caricata e unita la configurazione, come vengono valutate le policy e come il dashboard monitora l'attività dell'agente.
|
|
9
10
|
|
|
10
11
|
---
|
|
11
12
|
|
|
@@ -13,14 +14,14 @@ Questo documento spiega come failproofai funziona internamente: come il sistema
|
|
|
13
14
|
|
|
14
15
|
failproofai ha due sottosistemi indipendenti:
|
|
15
16
|
|
|
16
|
-
1. **
|
|
17
|
-
2. **Agent Monitor (Dashboard)** - Un'applicazione web Next.js per
|
|
17
|
+
1. **Hook handler** - Un veloce subprocess CLI che Claude Code invoca a ogni chiamata di strumento dell'agente. Valuta le policy e restituisce una decisione.
|
|
18
|
+
2. **Agent Monitor (Dashboard)** - Un'applicazione web Next.js per monitorare le sessioni dell'agente e gestire le policy.
|
|
18
19
|
|
|
19
|
-
Entrambi i sottosistemi condividono file di configurazione in `~/.failproofai/` e nella directory `.failproofai/` del progetto, ma vengono eseguiti come processi separati e comunicano solo
|
|
20
|
+
Entrambi i sottosistemi condividono i file di configurazione in `~/.failproofai/` e nella directory `.failproofai/` del progetto, ma vengono eseguiti come processi separati e comunicano solo attraverso il filesystem.
|
|
20
21
|
|
|
21
22
|
---
|
|
22
23
|
|
|
23
|
-
##
|
|
24
|
+
## Hook handler
|
|
24
25
|
|
|
25
26
|
### Integrazione con Claude Code
|
|
26
27
|
|
|
@@ -45,7 +46,7 @@ Quando esegui `failproofai policies --install`, scrive voci come questa in `~/.c
|
|
|
45
46
|
}
|
|
46
47
|
```
|
|
47
48
|
|
|
48
|
-
Claude Code quindi
|
|
49
|
+
Claude Code invoca quindi `failproofai --hook PreToolUse` come subprocess prima di ogni chiamata di strumento, passando un payload JSON su stdin.
|
|
49
50
|
|
|
50
51
|
### Formato del payload
|
|
51
52
|
|
|
@@ -61,9 +62,9 @@ Claude Code quindi richiama `failproofai --hook PreToolUse` come subprocess prim
|
|
|
61
62
|
}
|
|
62
63
|
```
|
|
63
64
|
|
|
64
|
-
Per eventi `PostToolUse`, il payload contiene anche `tool_result` con l'output dello strumento.
|
|
65
|
+
Per gli eventi `PostToolUse`, il payload contiene anche `tool_result` con l'output dello strumento.
|
|
65
66
|
|
|
66
|
-
|
|
67
|
+
L'handler applica un limite di stdin di 1 MB. I payload che superano questo limite vengono scartati e tutte le policy permettono implicitamente.
|
|
67
68
|
|
|
68
69
|
### Formato della risposta
|
|
69
70
|
|
|
@@ -95,17 +96,17 @@ Il gestore applica un limite di 1 MB per stdin. I payload che superano questo li
|
|
|
95
96
|
}
|
|
96
97
|
```
|
|
97
98
|
|
|
98
|
-
**
|
|
99
|
+
**Instruct per evento Stop:**
|
|
99
100
|
- Exit code: `2`
|
|
100
101
|
- Motivo scritto su stderr (non stdout)
|
|
101
102
|
|
|
102
103
|
**Allow:**
|
|
103
104
|
- Exit code: `0`
|
|
104
|
-
-
|
|
105
|
+
- stdout vuoto
|
|
105
106
|
|
|
106
|
-
**Allow con messaggio
|
|
107
|
+
**Allow con messaggio:**
|
|
107
108
|
|
|
108
|
-
|
|
109
|
+
`allow(message)` consente a una policy di inviare contesto informativo a Claude anche quando l'operazione è consentita. L'hook handler scrive il seguente JSON su **stdout** (non su un file di config — questa è la risposta dell'handler a Claude Code, proprio come le risposte deny e instruct sopra):
|
|
109
110
|
|
|
110
111
|
```json
|
|
111
112
|
// Written to stdout by the hook handler process
|
|
@@ -115,9 +116,9 @@ A partire da v0.0.2-beta.3, `allow(message)` consente a una politica di inviare
|
|
|
115
116
|
}
|
|
116
117
|
}
|
|
117
118
|
```
|
|
118
|
-
- Exit code: `0` (
|
|
119
|
-
- Quando più
|
|
120
|
-
- Se nessuna
|
|
119
|
+
- Exit code: `0` (operazione consentita)
|
|
120
|
+
- Quando più policy restituiscono `allow` con un messaggio, i loro messaggi vengono uniti con newline in un'unica stringa `additionalContext`
|
|
121
|
+
- Se nessuna policy fornisce un messaggio, stdout è vuoto (come prima)
|
|
121
122
|
|
|
122
123
|
### Pipeline di elaborazione
|
|
123
124
|
|
|
@@ -140,13 +141,13 @@ stdin JSON
|
|
|
140
141
|
→ exit
|
|
141
142
|
```
|
|
142
143
|
|
|
143
|
-
L'intero processo viene eseguito in meno di 100ms per
|
|
144
|
+
L'intero processo viene eseguito in meno di 100ms per payload tipici senza chiamate LLM.
|
|
144
145
|
|
|
145
146
|
---
|
|
146
147
|
|
|
147
148
|
## Caricamento della configurazione
|
|
148
149
|
|
|
149
|
-
`src/hooks/hooks-config.ts` implementa il caricamento della
|
|
150
|
+
`src/hooks/hooks-config.ts` implementa il caricamento della config a tre ambiti.
|
|
150
151
|
|
|
151
152
|
```text
|
|
152
153
|
[1] {cwd}/.failproofai/policies-config.json ← project (highest priority)
|
|
@@ -155,39 +156,39 @@ L'intero processo viene eseguito in meno di 100ms per i payload tipici senza chi
|
|
|
155
156
|
```
|
|
156
157
|
|
|
157
158
|
Logica di unione:
|
|
158
|
-
- `enabledPolicies` - unione
|
|
159
|
-
- `policyParams` - per
|
|
160
|
-
- `customPoliciesPath` - il primo file che
|
|
161
|
-
- `llm` - il primo file che
|
|
159
|
+
- `enabledPolicies` - unione deduplicated in tutti e tre i file
|
|
160
|
+
- `policyParams` - per policy, il primo file che lo definisce vince completamente
|
|
161
|
+
- `customPoliciesPath` - il primo file che lo definisce vince
|
|
162
|
+
- `llm` - il primo file che lo definisce vince
|
|
162
163
|
|
|
163
|
-
Il dashboard web utilizza `readHooksConfig()` (solo globale) per
|
|
164
|
+
Il dashboard web utilizza `readHooksConfig()` (solo globale) per leggere e scrivere, poiché non viene invocato con un cwd del progetto.
|
|
164
165
|
|
|
165
166
|
---
|
|
166
167
|
|
|
167
|
-
## Valutazione delle
|
|
168
|
+
## Valutazione delle policy
|
|
168
169
|
|
|
169
|
-
`src/hooks/policy-evaluator.ts` esegue le
|
|
170
|
+
`src/hooks/policy-evaluator.ts` esegue le policy in ordine.
|
|
170
171
|
|
|
171
|
-
Per ogni
|
|
172
|
+
Per ogni policy:
|
|
172
173
|
|
|
173
|
-
1. Cerca lo schema `params` della
|
|
174
|
-
2.
|
|
175
|
-
3.
|
|
174
|
+
1. Cerca lo schema `params` della policy (se ne ha uno).
|
|
175
|
+
2. Leggi `policyParams[policy.name]` dalla config unita.
|
|
176
|
+
3. Unisci i valori forniti dall'utente sui default dello schema per produrre `ctx.params`.
|
|
176
177
|
4. Chiama `policy.fn(ctx)` con il contesto risolto.
|
|
177
|
-
5. Se il risultato è `deny`,
|
|
178
|
+
5. Se il risultato è `deny`, fermati immediatamente e restituisci quella decisione.
|
|
178
179
|
6. Se il risultato è `instruct`, accumula il messaggio e continua.
|
|
179
|
-
7. Se il risultato è `allow`, continua
|
|
180
|
+
7. Se il risultato è `allow`, continua con la policy successiva.
|
|
180
181
|
|
|
181
|
-
Dopo che tutte le
|
|
182
|
-
- Se è stato restituito qualsiasi `deny`, emetti la risposta
|
|
183
|
-
- Se sono stati raccolti
|
|
182
|
+
Dopo che tutte le policy vengono eseguite:
|
|
183
|
+
- Se è stato restituito un qualsiasi `deny`, emetti la risposta deny.
|
|
184
|
+
- Se sono stati raccolti dei ritorni `instruct`, emetti un'unica risposta instruct con tutti i messaggi uniti.
|
|
184
185
|
- Altrimenti, emetti una risposta allow (stdout vuoto, exit 0).
|
|
185
186
|
|
|
186
187
|
---
|
|
187
188
|
|
|
188
|
-
##
|
|
189
|
+
## Policy built-in
|
|
189
190
|
|
|
190
|
-
`src/hooks/builtin-policies.ts` definisce tutte le 26
|
|
191
|
+
`src/hooks/builtin-policies.ts` definisce tutte le 26 policy built-in come oggetti `BuiltinPolicyDefinition`:
|
|
191
192
|
|
|
192
193
|
```typescript
|
|
193
194
|
interface BuiltinPolicyDefinition {
|
|
@@ -205,13 +206,13 @@ interface BuiltinPolicyDefinition {
|
|
|
205
206
|
}
|
|
206
207
|
```
|
|
207
208
|
|
|
208
|
-
Le
|
|
209
|
+
Le policy che accettano `params` dichiarano uno `PolicyParamsSchema` con tipi e default per ogni parametro. L'evaluator delle policy inietta i valori risolti in `ctx.params` prima di chiamare `fn`. Le funzioni delle policy leggono `ctx.params` senza null-guarding perché i default vengono sempre applicati per primi.
|
|
209
210
|
|
|
210
|
-
Il pattern matching all'interno delle
|
|
211
|
+
Il pattern matching all'interno delle policy utilizza token di comando analizzati (argv), non corrispondenza di stringhe grezze. Questo previene il bypass via iniezione di operatori shell (ad es. un pattern per `sudo systemctl status *` non può essere bypassato aggiungendo `; rm -rf /` al comando).
|
|
211
212
|
|
|
212
213
|
---
|
|
213
214
|
|
|
214
|
-
##
|
|
215
|
+
## Policy personalizzate
|
|
215
216
|
|
|
216
217
|
`src/hooks/custom-hooks-registry.ts` implementa un registro supportato da `globalThis`:
|
|
217
218
|
|
|
@@ -226,25 +227,25 @@ export function getCustomHooks(): CustomHook[] { ... }
|
|
|
226
227
|
export function clearCustomHooks(): void { ... } // used in tests
|
|
227
228
|
```
|
|
228
229
|
|
|
229
|
-
`src/hooks/custom-hooks-loader.ts` carica il file di
|
|
230
|
+
`src/hooks/custom-hooks-loader.ts` carica il file di policy dell'utente:
|
|
230
231
|
|
|
231
|
-
1. Leggi `customPoliciesPath` dalla
|
|
232
|
-
2. Risolvi al percorso assoluto;
|
|
232
|
+
1. Leggi `customPoliciesPath` dalla config; salta se assente.
|
|
233
|
+
2. Risolvi al percorso assoluto; controlla che il file esista.
|
|
233
234
|
3. Riscrivi tutti gli import `from "failproofai"` al percorso dist effettivo in modo che `customPolicies` si risolva nello stesso registro `globalThis`.
|
|
234
235
|
4. Riscrivi ricorsivamente gli import locali transitivi per garantire la compatibilità ESM.
|
|
235
236
|
5. Scrivi file `.mjs` temporanei e `import()` il file di entry.
|
|
236
237
|
6. Chiama `getCustomHooks()` per recuperare gli hook registrati.
|
|
237
|
-
7. Pulisci tutti i file
|
|
238
|
+
7. Pulisci tutti i file temp in un blocco `finally`.
|
|
238
239
|
|
|
239
|
-
In caso di errore (file non trovato, errore di sintassi, errore di import), l'errore viene registrato in `~/.failproofai/hook.log` e il loader restituisce un array vuoto. Le
|
|
240
|
+
In caso di errore (file non trovato, errore di sintassi, errore di import), l'errore viene registrato in `~/.failproofai/hook.log` e il loader restituisce un array vuoto. Le policy built-in non ne sono interessate.
|
|
240
241
|
|
|
241
|
-
Le
|
|
242
|
+
Le policy personalizzate vengono valutate dopo tutte le policy built-in. Un `deny` di policy personalizzata continua a fare short-circuit delle ulteriori policy personalizzate (ma tutte le built-in sono già state eseguite a questo punto).
|
|
242
243
|
|
|
243
244
|
---
|
|
244
245
|
|
|
245
|
-
##
|
|
246
|
+
## Registrazione dell'attività
|
|
246
247
|
|
|
247
|
-
Dopo ogni evento
|
|
248
|
+
Dopo ogni evento hook, l'handler aggiunge una riga JSONL a `~/.failproofai/hook-activity.jsonl`:
|
|
248
249
|
|
|
249
250
|
```json
|
|
250
251
|
{
|
|
@@ -259,7 +260,7 @@ Dopo ogni evento di hook, il gestore aggiunge una riga JSONL a `~/.failproofai/h
|
|
|
259
260
|
}
|
|
260
261
|
```
|
|
261
262
|
|
|
262
|
-
Una riga per
|
|
263
|
+
Una riga per policy che ha preso una decisione non-allow. Le decisioni allow non vengono registrate (per mantenere il file piccolo).
|
|
263
264
|
|
|
264
265
|
---
|
|
265
266
|
|
|
@@ -287,16 +288,16 @@ app/
|
|
|
287
288
|
|
|
288
289
|
**Flusso di dati:**
|
|
289
290
|
|
|
290
|
-
- I componenti pagina chiamano `lib/projects.ts` e `lib/log-entries.ts` per leggere i dati
|
|
291
|
-
- La pagina Policies utilizza Server Actions per tutte le mutazioni (toggle, aggiornamento params,
|
|
292
|
-
- Il visualizzatore di sessione
|
|
291
|
+
- I componenti pagina chiamano `lib/projects.ts` e `lib/log-entries.ts` per leggere i dati del progetto/sessione direttamente dal filesystem (nessun livello API per le letture).
|
|
292
|
+
- La pagina Policies utilizza Server Actions per tutte le mutazioni (toggle, aggiornamento params, install/remove).
|
|
293
|
+
- Il visualizzatore di sessione analizza il formato di trascritto JSONL di Claude e renderizza una timeline di messaggi e chiamate di strumento.
|
|
293
294
|
|
|
294
|
-
**Decisioni di
|
|
295
|
+
**Decisioni di progettazione chiave:**
|
|
295
296
|
|
|
296
297
|
- Nessun database - tutto lo stato persistente è in file semplici (`~/.failproofai/`, `~/.claude/projects/`).
|
|
297
298
|
- Server Actions per mutazioni - nessuna API REST necessaria per le operazioni CRUD.
|
|
298
|
-
- React Server Components per pagine di lettura - caricamento iniziale più veloce, nessun bundle client per il
|
|
299
|
-
- Componenti client solo dove è necessaria l'interattività (toggle
|
|
299
|
+
- React Server Components per le pagine di lettura - caricamento iniziale più veloce, nessun bundle client per il fetch dei dati.
|
|
300
|
+
- Componenti client solo dove è necessaria l'interattività (toggle policy, ricerca attività, visualizzatore log).
|
|
300
301
|
|
|
301
302
|
---
|
|
302
303
|
|
|
@@ -1,29 +1,28 @@
|
|
|
1
1
|
---
|
|
2
|
-
---
|
|
3
2
|
title: Configurazione
|
|
4
|
-
description: "Formato del file di configurazione, sistema a tre
|
|
3
|
+
description: "Formato del file di configurazione, sistema a tre livelli e regole di merge"
|
|
5
4
|
icon: gear
|
|
6
5
|
---
|
|
7
6
|
|
|
8
|
-
failproofai utilizza file di configurazione JSON per controllare quali policy sono attive, come si comportano e da dove vengono caricate le policy personalizzate. La configurazione è progettata per essere
|
|
7
|
+
failproofai utilizza file di configurazione JSON per controllare quali policy sono attive, come si comportano e da dove vengono caricate le policy personalizzate. La configurazione è progettata per essere facile da condividere con il tuo team - commitla nel tuo repository e ogni sviluppatore otterrà la stessa rete di sicurezza per l'agent.
|
|
9
8
|
|
|
10
9
|
---
|
|
11
10
|
|
|
12
|
-
##
|
|
11
|
+
## Ambiti di configurazione
|
|
13
12
|
|
|
14
|
-
Esistono tre
|
|
13
|
+
Esistono tre ambiti di configurazione, valutati in ordine di priorità:
|
|
15
14
|
|
|
16
|
-
|
|
|
17
|
-
|
|
18
|
-
| **project** | `.failproofai/policies-config.json` | Impostazioni per-
|
|
19
|
-
| **local** | `.failproofai/policies-config.local.json` | Override personali per-
|
|
20
|
-
| **global** | `~/.failproofai/policies-config.json` | Impostazioni predefinite a livello
|
|
15
|
+
| Ambito | Percorso file | Scopo |
|
|
16
|
+
|--------|---------------|-------|
|
|
17
|
+
| **project** | `.failproofai/policies-config.json` | Impostazioni per-repo, committate nel controllo versione |
|
|
18
|
+
| **local** | `.failproofai/policies-config.local.json` | Override personali per-repo, gitignored |
|
|
19
|
+
| **global** | `~/.failproofai/policies-config.json` | Impostazioni predefinite a livello utente su tutti i progetti |
|
|
21
20
|
|
|
22
21
|
Quando failproofai riceve un evento hook, carica e unisce tutti e tre i file che esistono per la directory di lavoro corrente.
|
|
23
22
|
|
|
24
23
|
### Regole di merge
|
|
25
24
|
|
|
26
|
-
**`enabledPolicies`** - l'unione di tutti e tre gli
|
|
25
|
+
**`enabledPolicies`** - l'unione di tutti e tre gli ambiti. Una policy abilitata a qualsiasi livello è attiva.
|
|
27
26
|
|
|
28
27
|
```text
|
|
29
28
|
project: ["block-sudo"]
|
|
@@ -33,7 +32,7 @@ global: ["block-sudo", "sanitize-api-keys"]
|
|
|
33
32
|
resolved: ["block-sudo", "block-rm-rf", "sanitize-api-keys"] ← unione deduplicated
|
|
34
33
|
```
|
|
35
34
|
|
|
36
|
-
**`policyParams`** - il primo
|
|
35
|
+
**`policyParams`** - il primo ambito che definisce i parametri per una determinata policy vince completamente. Non esiste un merge profondo dei valori all'interno dei parametri di una policy.
|
|
37
36
|
|
|
38
37
|
```text
|
|
39
38
|
project: block-sudo → { allowPatterns: ["sudo apt-get update"] }
|
|
@@ -43,16 +42,16 @@ resolved: { allowPatterns: ["sudo apt-get update"] } ← project vince, global
|
|
|
43
42
|
```
|
|
44
43
|
|
|
45
44
|
```text
|
|
46
|
-
project: (
|
|
47
|
-
local: (
|
|
45
|
+
project: (nessuna voce block-sudo)
|
|
46
|
+
local: (nessuna voce block-sudo)
|
|
48
47
|
global: block-sudo → { allowPatterns: ["sudo systemctl status"] }
|
|
49
48
|
|
|
50
|
-
resolved: { allowPatterns: ["sudo systemctl status"] } ← ricade
|
|
49
|
+
resolved: { allowPatterns: ["sudo systemctl status"] } ← ricade nel global
|
|
51
50
|
```
|
|
52
51
|
|
|
53
|
-
**`customPoliciesPath`** - il primo
|
|
52
|
+
**`customPoliciesPath`** - il primo ambito che lo definisce vince.
|
|
54
53
|
|
|
55
|
-
**`llm`** - il primo
|
|
54
|
+
**`llm`** - il primo ambito che lo definisce vince.
|
|
56
55
|
|
|
57
56
|
---
|
|
58
57
|
|
|
@@ -101,79 +100,79 @@ resolved: { allowPatterns: ["sudo systemctl status"] } ← ricade a global
|
|
|
101
100
|
|
|
102
101
|
### `enabledPolicies`
|
|
103
102
|
|
|
104
|
-
|
|
103
|
+
Tipo: `string[]`
|
|
105
104
|
|
|
106
|
-
Elenco dei nomi delle policy da abilitare. I nomi devono corrispondere esattamente agli identificatori delle policy mostrati da `failproofai policies`.
|
|
105
|
+
Elenco dei nomi delle policy da abilitare. I nomi devono corrispondere esattamente agli identificatori delle policy mostrati da `failproofai policies`. Consulta [Built-in Policies](/it/built-in-policies) per l'elenco completo.
|
|
107
106
|
|
|
108
107
|
Le policy non in `enabledPolicies` sono inattive, anche se hanno voci in `policyParams`.
|
|
109
108
|
|
|
110
109
|
### `policyParams`
|
|
111
110
|
|
|
112
|
-
|
|
111
|
+
Tipo: `Record<string, Record<string, unknown>>`
|
|
113
112
|
|
|
114
113
|
Override dei parametri per-policy. La chiave esterna è il nome della policy; le chiavi interne sono specifiche della policy. Ogni policy documenta i suoi parametri disponibili in [Built-in Policies](/it/built-in-policies).
|
|
115
114
|
|
|
116
115
|
Se una policy ha parametri ma non li specifichi, vengono utilizzati i valori predefiniti integrati della policy. Gli utenti che non configurano affatto `policyParams` ottengono un comportamento identico alle versioni precedenti.
|
|
117
116
|
|
|
118
|
-
Le chiavi sconosciute all'interno del blocco parametri di una policy vengono silenziosamente ignorate al momento dell'
|
|
117
|
+
Le chiavi sconosciute all'interno del blocco dei parametri di una policy vengono silenziosamente ignorate al momento dell'esecuzione dell'hook ma contrassegnate come avvisi quando esegui `failproofai policies`.
|
|
119
118
|
|
|
120
119
|
#### `hint` (cross-cutting)
|
|
121
120
|
|
|
122
|
-
|
|
121
|
+
Tipo: `string` (opzionale)
|
|
123
122
|
|
|
124
|
-
Un messaggio aggiunto al motivo quando una policy restituisce `deny` o `instruct`. Usalo per dare a Claude una guida
|
|
123
|
+
Un messaggio aggiunto al motivo quando una policy restituisce `deny` o `instruct`. Usalo per dare a Claude una guida pratica senza modificare la policy stessa.
|
|
125
124
|
|
|
126
|
-
Funziona con qualsiasi tipo di policy —
|
|
125
|
+
Funziona con qualsiasi tipo di policy — built-in, personalizzata (`custom/`), convenzione progetto (`.failproofai-project/`), o convenzione utente (`.failproofai-user/`).
|
|
127
126
|
|
|
128
127
|
```json
|
|
129
128
|
{
|
|
130
129
|
"policyParams": {
|
|
131
130
|
"block-force-push": {
|
|
132
|
-
"hint": "
|
|
131
|
+
"hint": "Prova a creare un nuovo branch."
|
|
133
132
|
},
|
|
134
133
|
"block-sudo": {
|
|
135
134
|
"allowPatterns": ["sudo apt-get"],
|
|
136
|
-
"hint": "
|
|
135
|
+
"hint": "Usa apt-get direttamente senza sudo."
|
|
137
136
|
},
|
|
138
137
|
"custom/my-policy": {
|
|
139
|
-
"hint": "
|
|
138
|
+
"hint": "Chiedi prima l'approvazione all'utente."
|
|
140
139
|
}
|
|
141
140
|
}
|
|
142
141
|
}
|
|
143
142
|
```
|
|
144
143
|
|
|
145
|
-
Quando `block-force-push` nega, Claude vede: *"
|
|
144
|
+
Quando `block-force-push` nega, Claude vede: *"Il force-push è bloccato. Prova a creare un nuovo branch."*
|
|
146
145
|
|
|
147
|
-
I valori non
|
|
146
|
+
I valori non-string e le stringhe vuote vengono silenziosamente ignorate. Se `hint` non è impostato, il comportamento è invariato (backward-compatible).
|
|
148
147
|
|
|
149
148
|
### `customPoliciesPath`
|
|
150
149
|
|
|
151
|
-
|
|
150
|
+
Tipo: `string` (percorso assoluto)
|
|
152
151
|
|
|
153
|
-
Percorso
|
|
152
|
+
Percorso di un file JavaScript contenente policy hook personalizzate. Viene impostato automaticamente da `failproofai policies --install --custom <path>` (il percorso viene risolto in assoluto prima di essere archiviato).
|
|
154
153
|
|
|
155
|
-
Il file viene caricato
|
|
154
|
+
Il file viene caricato da zero su ogni evento hook - non esiste alcun caching. Consulta [Custom Policies](/it/custom-policies) per i dettagli sulla creazione.
|
|
156
155
|
|
|
157
|
-
### Policy basate su convenzione
|
|
156
|
+
### Policy basate su convenzione
|
|
158
157
|
|
|
159
158
|
Oltre al `customPoliciesPath` esplicito, failproofai scopre e carica automaticamente i file di policy dalle directory `.failproofai/policies/`:
|
|
160
159
|
|
|
161
|
-
| Livello | Directory |
|
|
162
|
-
|
|
163
|
-
|
|
|
164
|
-
|
|
|
160
|
+
| Livello | Directory | Ambito |
|
|
161
|
+
|---------|-----------|--------|
|
|
162
|
+
| Progetto | `.failproofai/policies/` | Condiviso con il team tramite controllo versione |
|
|
163
|
+
| Utente | `~/.failproofai/policies/` | Personale, si applica a tutti i progetti |
|
|
165
164
|
|
|
166
|
-
**
|
|
165
|
+
**Corrispondenza file:** Solo i file che corrispondono a `*policies.{js,mjs,ts}` vengono caricati (ad es. `security-policies.mjs`, `workflow-policies.js`). Gli altri file nella directory vengono ignorati.
|
|
167
166
|
|
|
168
|
-
**Nessuna configurazione necessaria:** Le policy di convenzione non richiedono voci in `policies-config.json`. Basta
|
|
167
|
+
**Nessuna configurazione necessaria:** Le policy di convenzione non richiedono voci in `policies-config.json`. Basta depositare file nella directory e verranno caricati al prossimo evento hook.
|
|
169
168
|
|
|
170
|
-
**
|
|
169
|
+
**Caricamento union:** Entrambe le directory di convenzione progetto e utente vengono scansionate. Tutti i file corrispondenti da entrambi i livelli vengono caricati (a differenza di `customPoliciesPath` che utilizza il primo ambito che vince).
|
|
171
170
|
|
|
172
|
-
|
|
171
|
+
Consulta [Custom Policies](/it/custom-policies) per ulteriori dettagli ed esempi.
|
|
173
172
|
|
|
174
173
|
### `llm`
|
|
175
174
|
|
|
176
|
-
|
|
175
|
+
Tipo: `object` (opzionale)
|
|
177
176
|
|
|
178
177
|
Configurazione del client LLM per le policy che effettuano chiamate AI. Non richiesto per la maggior parte delle configurazioni.
|
|
179
178
|
|
|
@@ -188,7 +187,7 @@ Configurazione del client LLM per le policy che effettuano chiamate AI. Non rich
|
|
|
188
187
|
|
|
189
188
|
---
|
|
190
189
|
|
|
191
|
-
## Gestione della configurazione
|
|
190
|
+
## Gestione della configurazione dalla CLI
|
|
192
191
|
|
|
193
192
|
I comandi `policies --install` e `policies --uninstall` scrivono nel `settings.json` di Claude Code (i punti di ingresso dell'hook), mentre `policies-config.json` è il file che gestisci direttamente. I due sono separati:
|
|
194
193
|
|
|
@@ -199,9 +198,9 @@ Puoi modificare `policies-config.json` direttamente in qualsiasi momento; le mod
|
|
|
199
198
|
|
|
200
199
|
---
|
|
201
200
|
|
|
202
|
-
## Esempio:
|
|
201
|
+
## Esempio: configurazione a livello di progetto con impostazioni predefinite del team
|
|
203
202
|
|
|
204
|
-
Committa `.failproofai/policies-config.json` nel tuo
|
|
203
|
+
Committa `.failproofai/policies-config.json` nel tuo repository:
|
|
205
204
|
|
|
206
205
|
```json
|
|
207
206
|
{
|
|
@@ -220,4 +219,4 @@ Committa `.failproofai/policies-config.json` nel tuo repo:
|
|
|
220
219
|
}
|
|
221
220
|
```
|
|
222
221
|
|
|
223
|
-
Ogni sviluppatore può quindi creare `.failproofai/policies-config.local.json` (gitignored) per override personali senza influenzare i compagni di squadra.
|
|
222
|
+
Ogni sviluppatore può quindi creare `.failproofai/policies-config.local.json` (gitignored) per gli override personali senza influenzare i compagni di squadra.
|