@aimarket/warden 0.22.4 → 0.24.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.
Files changed (79) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/README-es.md +19 -9
  3. package/README-fr.md +19 -9
  4. package/README-ru.md +19 -9
  5. package/README-zh.md +18 -9
  6. package/README.md +29 -11
  7. package/codex-hooks/hooks.json +17 -0
  8. package/codex-hooks/requirements.toml +38 -0
  9. package/codex-hooks/scripts/codex-hook.mjs +15 -0
  10. package/codex-hooks/scripts/flow-guard-answer.mjs +228 -0
  11. package/codex-hooks/scripts/flow-guard-classify.mjs +224 -0
  12. package/codex-hooks/scripts/flow-guard-codex.mjs +222 -0
  13. package/codex-hooks/scripts/flow-guard-constraints.mjs +69 -0
  14. package/codex-hooks/scripts/flow-guard-decode.mjs +149 -0
  15. package/codex-hooks/scripts/flow-guard-destinations.mjs +158 -0
  16. package/codex-hooks/scripts/flow-guard-fingerprints.mjs +180 -0
  17. package/codex-hooks/scripts/flow-guard-fragments.mjs +122 -0
  18. package/codex-hooks/scripts/flow-guard-instructions.mjs +36 -0
  19. package/codex-hooks/scripts/flow-guard-labels.mjs +55 -0
  20. package/codex-hooks/scripts/flow-guard-leak.mjs +135 -0
  21. package/codex-hooks/scripts/flow-guard-paths.mjs +80 -0
  22. package/codex-hooks/scripts/flow-guard-policy.mjs +179 -0
  23. package/codex-hooks/scripts/flow-guard-post.mjs +131 -0
  24. package/codex-hooks/scripts/flow-guard-pre.mjs +339 -0
  25. package/codex-hooks/scripts/flow-guard-screen.mjs +558 -0
  26. package/codex-hooks/scripts/flow-guard-state.mjs +129 -0
  27. package/codex-hooks/scripts/flow-guard-text.mjs +46 -0
  28. package/codex-hooks/scripts/flow-guard-types.mjs +2 -0
  29. package/codex-hooks/scripts/flow-guard-unattended.mjs +22 -0
  30. package/codex-hooks/scripts/flow-guard.mjs +103 -0
  31. package/dist/flow-guard-codex.d.ts +32 -0
  32. package/dist/flow-guard-codex.d.ts.map +1 -0
  33. package/dist/flow-guard-codex.js +222 -0
  34. package/dist/flow-guard-codex.js.map +1 -0
  35. package/dist/flow-guard-fingerprints.d.ts +4 -0
  36. package/dist/flow-guard-fingerprints.d.ts.map +1 -1
  37. package/dist/flow-guard-fingerprints.js +17 -1
  38. package/dist/flow-guard-fingerprints.js.map +1 -1
  39. package/dist/flow-guard-paths.d.ts.map +1 -1
  40. package/dist/flow-guard-paths.js +9 -1
  41. package/dist/flow-guard-paths.js.map +1 -1
  42. package/dist/flow-guard-post.js +2 -2
  43. package/dist/flow-guard-post.js.map +1 -1
  44. package/dist/flow-guard-pre.d.ts +8 -1
  45. package/dist/flow-guard-pre.d.ts.map +1 -1
  46. package/dist/flow-guard-pre.js +5 -1
  47. package/dist/flow-guard-pre.js.map +1 -1
  48. package/dist/flow-guard-unattended.d.ts +27 -0
  49. package/dist/flow-guard-unattended.d.ts.map +1 -0
  50. package/dist/flow-guard-unattended.js +22 -0
  51. package/dist/flow-guard-unattended.js.map +1 -0
  52. package/dist/flow-guard.d.ts +2 -1
  53. package/dist/flow-guard.d.ts.map +1 -1
  54. package/dist/flow-guard.js +1 -1
  55. package/dist/flow-guard.js.map +1 -1
  56. package/dist/opencode-plugin.d.ts +35 -0
  57. package/dist/opencode-plugin.d.ts.map +1 -0
  58. package/dist/opencode-plugin.js +215 -0
  59. package/dist/opencode-plugin.js.map +1 -0
  60. package/docs/codex.es.md +260 -0
  61. package/docs/codex.fr.md +262 -0
  62. package/docs/codex.md +251 -0
  63. package/docs/codex.ru.md +254 -0
  64. package/docs/codex.zh.md +232 -0
  65. package/docs/flow-guard.es.md +1 -1
  66. package/docs/flow-guard.fr.md +1 -1
  67. package/docs/flow-guard.md +1 -1
  68. package/docs/flow-guard.ru.md +1 -1
  69. package/docs/flow-guard.zh.md +1 -1
  70. package/docs/gates.md +1 -1
  71. package/docs/opencode.md +153 -0
  72. package/docs/scan.es.md +2 -2
  73. package/docs/scan.fr.md +2 -2
  74. package/docs/scan.md +2 -2
  75. package/docs/scan.ru.md +2 -2
  76. package/docs/scan.zh.md +2 -2
  77. package/opencode-plugin/warden.js +10 -0
  78. package/package.json +17 -2
  79. package/scripts/codex-live-check.sh +109 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,58 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.24.0 — 2026-11-08 (Codex flow guard)
4
+
5
+ - **Flow guard for OpenAI Codex** (`codex-hooks/`, `@aimarket/warden/codex`, [docs/codex.md](docs/codex.md) in five
6
+ languages): the Claude Code flow guard through Codex's command hooks (`PreToolUse`, `PostToolUse`,
7
+ `UserPromptSubmit`, `Stop`) for the CLI, `codex exec`, the desktop app and Multica runtimes. Codex has no
8
+ `permissionDecision: "ask"` (it treats it as a failed hook and runs the call), so the adapter never prints it: a
9
+ question becomes `deny` or a logged pass by `block` (`WARDEN_CODEX_BLOCK=data|all`, as for OpenCode). It fails
10
+ closed: unreadable input, an unknown event, a missing guard file or an exception deny PreToolUse, and a result that
11
+ cannot be recorded denies the rest of the session. Codex tools map to the guard's vocabulary (`Bash`/`exec_command`,
12
+ `apply_patch` → one `Write` per file, `mcp__*`, `view_image` → `Read`, others unlabelled); subagents share the
13
+ parent's state through Codex's parent `session_id`; session ids are namespaced `codex:<id>`.
14
+ - `codex-hooks/requirements.toml`: managed hooks for `/etc/codex/requirements.toml` with
15
+ `allow_managed_hooks_only = true`; `codex-hooks/hooks.json` for one person's `~/.codex/hooks.json`. The build copies
16
+ the flow-guard parts next to `codex-hook.mjs`, as for the Claude Code plugin.
17
+ - Protected paths: any `.codex/` folder, `/etc/codex/` and `$CODEX_HOME`. Secret path: `~/.codex/auth.json`.
18
+ - Red-team replay `flow-redteam.mjs --codex=MODE` replays the 28 attacks in Codex's tool vocabulary: `all` 0 of 28,
19
+ `data` 3 of 28 (the same three action-only attacks as OpenCode). `scripts/codex-live-check.sh` stages the attack in a
20
+ real Codex session on localhost. Live run 2026-11-07 (Codex CLI 0.167.0-alpha.3): with the user asking for every step,
21
+ the `curl` sending `.env` got `deny` (`reason: secret`) in `data` and `all`; the listener received nothing.
22
+ - The unattended `block` logic (`refuses`, `patchFiles`) moved to `src/flow-guard-unattended.ts`, shared by the
23
+ OpenCode and Codex adapters; `@aimarket/warden/opencode` re-exports both unchanged.
24
+ - OpenCode guide, "Where to put it when agents share a runtime": keep the guard in a root-owned folder where nothing
25
+ on its path belongs to the agent user, and load it with `OPENCODE_CONFIG_DIR`. Mount it writable, because OpenCode
26
+ writes a `.gitignore` into each config folder. On our own Multica daemon (2026-11-05) the agent user could not
27
+ change a guard file, but could `mv` the folder holding it, so later sessions started without the guard.
28
+ - READMEs: the scanner-comparison line gives 171 of 218 MCPTox held-out tools with the ruleset of that comparison
29
+ (v12). The release notes give 210 for v16.
30
+ - Repository only (not in the package): the landing page names the ruleset that ships (v17, 40 rules) and pins
31
+ 0.24.0 again. A regeneration on 2026-11-07 from a development build had put `0.23.1-dev.20261107` and ruleset
32
+ v18 there.
33
+
34
+ ## 0.23.0 — 2026-11-04 (OpenCode flow guard)
35
+
36
+ - **Flow guard for OpenCode** (`@aimarket/warden/opencode`, [docs/opencode.md](docs/opencode.md)): the Claude Code
37
+ flow guard through OpenCode's plugin hooks (`tool.execute.before/after`, `chat.message`, `shell.env`), for agents
38
+ that run unattended. `block: "data"` (default) refuses every call that involves data or a sensitive payload and
39
+ lets action-only calls run with a log line; `block: "all"` refuses everything the Claude hook would ask about.
40
+ `shell.env` blanks listed keys for shell commands. Red-team replay (`flow-redteam.mjs --opencode=MODE`): `all`
41
+ 0 of 28, `data` 3 of 28 (three action-only attacks, listed in the doc); the Claude Code gate stays 0 of 28.
42
+ - Subagents share the guard: OpenCode runs a `task` in a child session, and the adapter keys the flow state by the
43
+ root of the session tree (parents from `session.created`/`session.updated`, else the SDK client), so an injected
44
+ parent cannot hand the read-and-send to a fresh, untainted child; a child's prompt is not recorded as the user's
45
+ words. A result that cannot be recorded refuses the rest of that tree. Path classification uses the session's
46
+ directory, not the model's `workdir`.
47
+ - `flowPre` takes an optional fourth argument that receives the decision's reason and whether its payload is
48
+ sensitive. The hook output is unchanged.
49
+ - A canonical UUID is a record id, not personal data: `piiTokens` skips it, and private-text fingerprints drop
50
+ UUIDs except on a line that names a credential (`withoutRecordIds`). An agent passing back the issue id it read
51
+ had its report refused (found in a live Multica run); a UUID-shaped key read from an ordinary file still is.
52
+ - Secret formats: Telegram bot tokens and AIMarket hub API keys (`aimk_…`). Secret paths: OpenCode's
53
+ `~/.local/share/opencode/auth.json`, Multica's `~/.multica/config.json`. Protected paths: `~/.config/opencode/`,
54
+ `.opencode/`, `opencode.json(c)`.
55
+
3
56
  ## 0.22.4 — 2026-11-01 (ruleset v17)
4
57
 
5
58
  - `TOOL_DEF_CROSS_TOOL` catches a tool that adds a fixed address to another server's tool. DevToolLab's
package/README-es.md CHANGED
@@ -12,7 +12,7 @@
12
12
  <a href="https://glama.ai/mcp/servers/alexar76/warden"><img src="https://glama.ai/mcp/servers/alexar76/warden/badges/score.svg" alt="warden MCP server" /></a>
13
13
  <a href="https://warden.modelmarket.dev/"><img src="https://img.shields.io/npm/v/@aimarket/warden?color=cb3837&label=npm" alt="npm version" /></a>
14
14
  <img src="docs/badges/deps.svg" alt="Cero dependencias de ejecución" />
15
- <img src="docs/badges/tests.svg" alt="1400 pruebas en verde" />
15
+ <img src="docs/badges/tests.svg" alt="1517 pruebas en verde" />
16
16
  <img src="docs/badges/node.svg" alt="Node >= 20" />
17
17
  <a href="LICENSE"><img src="docs/badges/license.svg" alt="Licencia: MIT" /></a>
18
18
  </p>
@@ -33,11 +33,11 @@
33
33
  **Revisa todos los servidores MCP de tu máquina.** Sin cuenta, sin clave de API, sin modelo. El único tráfico de red va a los servidores de tu configuración.
34
34
 
35
35
  ```bash
36
- npx -y @aimarket/warden@0.22.4 scan
36
+ npx -y @aimarket/warden@0.24.0 scan
37
37
  ```
38
38
 
39
39
  ```text
40
- WARDEN scan 0.22.4 · ruleset 17 sha256-UOfK25xo6D8v… · block at high
40
+ WARDEN scan 0.24.0 · ruleset 17 sha256-UOfK25xo6D8v… · block at high
41
41
  read .mcp.json (claude-code, 3 servers)
42
42
 
43
43
  ✓ allow notes claude-code 1 tool · score 0.90
@@ -48,7 +48,7 @@ WARDEN scan 0.22.4 · ruleset 17 sha256-UOfK25xo6D8v… · block at high
48
48
  Details: warden-mcp scan --json, or --markdown FILE. To review a changed server: warden-mcp scan --lock warden.lock.json --update-lock.
49
49
  ```
50
50
 
51
- Frente a otros cuatro escáneres de código abierto sobre los mismos servidores, cada uno en un contenedor gVisor sin red: en la mitad reservada de MCPTox (un benchmark de AAAI 2026; las reglas de WARDEN se escribieron con la otra mitad) WARDEN bloquea 171 de 218 herramientas envenenadas, los demás entre 8 y 41. En 986 servidores públicos WARDEN bloquea 3 y en 14 933 paquetes de npm y PyPI, 369; mcp-shield bloquea 343 y 5354. [Método y todas las cifras](docs/scanner-comparison.es.md) · [guía de scan](docs/scan.es.md).
51
+ Frente a otros cuatro escáneres de código abierto sobre los mismos servidores, cada uno en un contenedor gVisor sin red: en la mitad reservada de MCPTox (un benchmark de AAAI 2026; las reglas de WARDEN se escribieron con la otra mitad) WARDEN bloqueó 171 de 218 herramientas envenenadas con las reglas de esa comparación (v12) y bloquea 210 desde el ruleset v16, los demás entre 8 y 41. En 986 servidores públicos WARDEN bloquea 3 y en 14 933 paquetes de npm y PyPI, 369; mcp-shield bloquea 343 y 5354. [Método y todas las cifras](docs/scanner-comparison.es.md) · [guía de scan](docs/scan.es.md).
52
52
  <!-- /warden-try -->
53
53
 
54
54
  **Guardia de flujo (código local, 2026-10-23).** Tras credenciales y texto externo, llamadas salientes/MCP y escrituras normales del proyecto requieren revisión, incluso con partes diminutas o codificación desconocida. Solicitudes públicas exactas revisadas por el operador pueden ejecutarse una vez por sesión; no eximen fugas detectadas ni análisis incompletos. Prueba: 0/16 ataques automáticos en ambos perfiles; revisión inocua 12/12 por defecto, 0/12 con reglas exactas. Compromiso explícito de uso, no decodificación universal. El mismo conjunto sigue en 0/23 entregados por completo. Producción/npm no cambian. [Política, pruebas y límites](docs/flow-guard.es.md).
@@ -108,14 +108,14 @@ Operaciones limitadas explícitas: `node dist/mcp-server.js task`. [Adaptador, p
108
108
  "mcpServers": {
109
109
  "filesystem": {
110
110
  "command": "npx",
111
- "args": ["-y", "@aimarket/warden@0.22.4", "wrap", "--id", "filesystem", "--",
111
+ "args": ["-y", "@aimarket/warden@0.24.0", "wrap", "--id", "filesystem", "--",
112
112
  "npx", "-y", "@modelcontextprotocol/server-filesystem", "/Users/me/docs"]
113
113
  }
114
114
  }
115
115
  }
116
116
  ```
117
117
 
118
- Especifique siempre `--id`: sin él, cambiar los argumentos crea otra identidad y otro primer contacto. Con un ID estable, cambiar el comando o una ruta produce `SERVER_IDENTITY_DRIFT`. El hijo hereda el entorno, excluido de la identidad. `npm install -g @aimarket/warden@0.22.4` y el comando `warden-mcp` evitan arranques fríos repetidos de `npx`.
118
+ Especifique siempre `--id`: sin él, cambiar los argumentos crea otra identidad y otro primer contacto. Con un ID estable, cambiar el comando o una ruta produce `SERVER_IDENTITY_DRIFT`. El hijo hereda el entorno, excluido de la identidad. `npm install -g @aimarket/warden@0.24.0` y el comando `warden-mcp` evitan arranques fríos repetidos de `npx`.
119
119
 
120
120
  **Herramientas sensibles.** `sensitiveToolPatterns` en un archivo de política (`--policy policy.json` con `{"sensitiveToolPatterns": ["*delete*", "*transfer*"]}`, comodines `*` sin distinguir mayúsculas) hace que cada llamada a una herramienta que coincida espere a una persona: `wrap` pregunta mediante el propio formulario del cliente (elicitation de MCP) con la herramienta, el servidor y los argumentos, y solo una respuesta aceptada con la casilla marcada deja pasar esa llamada. La casilla empieza desmarcada, así que un cliente que acepta formularios con sus valores por defecto no aprueba nada. Un cliente sin formulario de elicitation recibe un rechazo y el servidor nunca recibe la llamada; `--ask refuse` rechaza sin preguntar. Si el cliente cancela la llamada mientras la persona decide, o las definiciones cambian entretanto, no se envía. Antes de 0.20.0 `wrap` aceptaba estos patrones sin aplicarlos. Con `--flow`, un envío por el que la guardia de flujo preguntaría se pregunta igual.
121
121
 
@@ -140,15 +140,24 @@ Claude Desktop en macOS: `~/Library/Logs/Claude/mcp-server-<nombre>.log`. En Cur
140
140
  | `--audit-only` | Modo diagnóstico; desactivado por defecto |
141
141
  | `--ask elicit\|refuse` | Una llamada que necesita el sí de una persona (herramienta sensible, pregunta de la guardia de flujo): `elicit` (por defecto) pregunta con el formulario de elicitation MCP del cliente y rechaza si no lo tiene; `refuse` siempre rechaza |
142
142
 
143
+ ## Proteger un agente de Codex
144
+
145
+ La misma guardia de flujo para OpenAI Codex (CLI, `codex exec`, aplicación de escritorio, runtimes de Multica), mediante
146
+ los hooks de comando de Codex. Codex no tiene `ask` y ejecuta la llamada cuando un hook falla, así que el adaptador
147
+ nunca pregunta: una pregunta se convierte en rechazo o en paso registrado (`block: data|all`), y cualquier fallo
148
+ deniega. En un servidor de runtime, instálala como hooks gestionados en `/etc/codex/requirements.toml`. Los esquemas
149
+ para Multica y los límites están en [docs/codex.es.md](docs/codex.es.md) (red team en el vocabulario de Codex: `all`
150
+ 0 de 28, `data` 3 de 28, los mismos tres que OpenCode). Código local, aún no publicado.
151
+
143
152
  ## Analiza todos los servidores que inician tus clientes
144
153
 
145
154
  ```bash
146
- npx -y @aimarket/warden@0.22.4 scan
155
+ npx -y @aimarket/warden@0.24.0 scan
147
156
  ```
148
157
 
149
158
  Lee las configuraciones MCP de Claude Code, Claude Desktop, Cursor, VS Code y Windsurf, se conecta a cada servidor que inician y revisa las definiciones de herramientas antes de que un modelo las vea. Imprime una tabla, JSON, SARIF o Markdown, y sale con 1 cuando bloquea un servidor; `--no-launch` no inicia nada. En un repositorio, `warden.lock.json` convierte un cambio en las definiciones en un diff revisable, y la CI falla ante un servidor nuevo o modificado. También como GitHub Action (`uses: alexar76/warden@v0.21.0`), hooks de pre-commit y plugin de Claude Code (`/plugin marketplace add alexar76/warden`). `--histor` pregunta al registro público HISTOR si un servidor te sirve lo mismo que a todos; para un servidor remoto envía el endpoint y un digest; para un servidor stdio que arranca desde npm o PyPI, el nombre del paquete (`npm:<nombre>`, `pypi:<nombre>`, que HISTOR ejecuta en un sandbox gVisor) y un digest; nunca el texto de las herramientas. Un clasificador opcional (`--classifier-url`, `--classifier-model`) añade la lectura de un modelo que tú eliges, local o alojado, para lo que ninguna regla nombra. Consulta la [guía de scan](docs/scan.es.md). Cómo se compara con otros dos escáneres sobre los mismos servidores: [comparación de escáneres](docs/scanner-comparison.es.md).
150
159
 
151
- **Para el editor de un servidor.** Si tu servidor lista otras herramientas donde está instalado algo que el sandbox de HISTOR no tiene —el runner de un lanzador, uno por sistema operativo—, `npx -y @aimarket/warden@0.22.4 declare --out mcp-tool-sets.json -- <tu servidor>` escribe esos conjuntos en un archivo que publicas en tu propio dominio, y quienes los reciben ven la declaración del editor en lugar de un conjunto desconocido. Consulta la [guía de scan](docs/scan.es.md).
160
+ **Para el editor de un servidor.** Si tu servidor lista otras herramientas donde está instalado algo que el sandbox de HISTOR no tiene —el runner de un lanzador, uno por sistema operativo—, `npx -y @aimarket/warden@0.24.0 declare --out mcp-tool-sets.json -- <tu servidor>` escribe esos conjuntos en un archivo que publicas en tu propio dominio, y quienes los reciben ven la declaración del editor en lugar de un conjunto desconocido. Consulta la [guía de scan](docs/scan.es.md).
152
161
 
153
162
  ## Lo que WARDEN no hace
154
163
 
@@ -344,6 +353,7 @@ comprobarlas: [Identidades ERC-8004](https://github.com/alexar76/aicom/blob/main
344
353
  | [Estudio de campo: 1 108 servidores MCP públicos](docs/mcp-survey.es.md) | Qué decidió WARDEN sobre definiciones de herramienta reales de terceros — 50 servidores bloqueados, 4 sustentados, y las seis formas en que el resto se equivocó |
345
354
  | [Comparación de escáneres](docs/scanner-comparison.es.md) | WARDEN, mcp-audit, mcp-shield, truecopy y mcpsentry sobre los mismos servidores, sobre 14 933 paquetes de npm y PyPI y sobre el benchmark MCPTox, con cada juicio, el manifiesto y el banco de pruebas |
346
355
  | [Guardián de flujos](docs/flow-guard.es.md) | La protección en ejecución del plugin de Claude Code: texto ajeno, datos privados, llamadas salientes; la medición en AgentDojo y sus límites |
356
+ | [Guardia de flujo para Codex](docs/codex.es.md) | Hooks de Codex: sin `ask`, falla cerrado, hooks gestionados, esquemas para Multica |
347
357
  | [Nueva comparación del modelo](docs/flow-guard-model-comparison-2026-10-25.es.md) | 720 respuestas: mejora en casos conocidos, incertidumbre, canal de avisos y ninguna corrección de ID observada por Stop |
348
358
  | [Glama / Docker](docs/GLAMA.md) | MCP stdio, health check, Build steps / CMD |
349
359
  | [Security](SECURITY.md) | Cómo informar de un bypass del cortafuegos |
@@ -368,7 +378,7 @@ comprobarlas: [Identidades ERC-8004](https://github.com/alexar76/aicom/blob/main
368
378
  ## Desarrollo
369
379
 
370
380
  ```bash
371
- npm install && npm run build && npm test # 1400 pruebas
381
+ npm install && npm run build && npm test # 1517 pruebas
372
382
  ```
373
383
 
374
384
  `test/packaging.test.ts` es lo que mantiene honesto el titular: falla si aparece una dependencia de
package/README-fr.md CHANGED
@@ -12,7 +12,7 @@
12
12
  <a href="https://glama.ai/mcp/servers/alexar76/warden"><img src="https://glama.ai/mcp/servers/alexar76/warden/badges/score.svg" alt="warden MCP server" /></a>
13
13
  <a href="https://warden.modelmarket.dev/"><img src="https://img.shields.io/npm/v/@aimarket/warden?color=cb3837&label=npm" alt="version npm" /></a>
14
14
  <img src="docs/badges/deps.svg" alt="Zéro dépendance d'exécution" />
15
- <img src="docs/badges/tests.svg" alt="1400 tests au vert" />
15
+ <img src="docs/badges/tests.svg" alt="1517 tests au vert" />
16
16
  <img src="docs/badges/node.svg" alt="Node >= 20" />
17
17
  <a href="LICENSE"><img src="docs/badges/license.svg" alt="Licence : MIT" /></a>
18
18
  </p>
@@ -33,11 +33,11 @@
33
33
  **Vérifiez tous les serveurs MCP de votre machine.** Pas de compte, pas de clé d’API, pas de modèle. Le seul trafic réseau va vers les serveurs de votre configuration.
34
34
 
35
35
  ```bash
36
- npx -y @aimarket/warden@0.22.4 scan
36
+ npx -y @aimarket/warden@0.24.0 scan
37
37
  ```
38
38
 
39
39
  ```text
40
- WARDEN scan 0.22.4 · ruleset 17 sha256-UOfK25xo6D8v… · block at high
40
+ WARDEN scan 0.24.0 · ruleset 17 sha256-UOfK25xo6D8v… · block at high
41
41
  read .mcp.json (claude-code, 3 servers)
42
42
 
43
43
  ✓ allow notes claude-code 1 tool · score 0.90
@@ -48,7 +48,7 @@ WARDEN scan 0.22.4 · ruleset 17 sha256-UOfK25xo6D8v… · block at high
48
48
  Details: warden-mcp scan --json, or --markdown FILE. To review a changed server: warden-mcp scan --lock warden.lock.json --update-lock.
49
49
  ```
50
50
 
51
- Face à quatre autres scanners open source sur les mêmes serveurs, chacun dans un conteneur gVisor sans réseau : sur la moitié réservée de MCPTox (un benchmark d’AAAI 2026 ; les règles de WARDEN ont été écrites à partir de l’autre moitié), WARDEN bloque 171 des 218 outils empoisonnés, les autres entre 8 et 41. Sur 986 serveurs publics, WARDEN en bloque 3 et sur 14 933 paquets npm et PyPI, 369 ; mcp-shield en bloque 343 et 5 354. [Méthode et tous les chiffres](docs/scanner-comparison.fr.md) · [guide de scan](docs/scan.fr.md).
51
+ Face à quatre autres scanners open source sur les mêmes serveurs, chacun dans un conteneur gVisor sans réseau : sur la moitié réservée de MCPTox (un benchmark d’AAAI 2026 ; les règles de WARDEN ont été écrites à partir de l’autre moitié), WARDEN bloquait 171 des 218 outils empoisonnés avec les règles de cette comparaison (v12) et en bloque 210 depuis le ruleset v16, les autres entre 8 et 41. Sur 986 serveurs publics, WARDEN en bloque 3 et sur 14 933 paquets npm et PyPI, 369 ; mcp-shield en bloque 343 et 5 354. [Méthode et tous les chiffres](docs/scanner-comparison.fr.md) · [guide de scan](docs/scan.fr.md).
52
52
  <!-- /warden-try -->
53
53
 
54
54
  **Garde de flux (code local, 2026-10-23).** Après identifiants et texte extérieur, appels sortants/MCP et écritures ordinaires du projet imposent vérification, même pour fragments minuscules ou encodages inconnus. Des requêtes publiques exactes vérifiées par l’opérateur peuvent passer une fois par session ; elles ne dispensent pas les fuites reconnues ni analyses incomplètes. Scénario : 0/16 attaques automatiques dans les deux profils ; confirmations innocentes 12/12 par défaut, 0/12 avec règles exactes. Compromis explicite, pas décodeur universel. Même ensemble : 0/23 livrés intégralement. Production/npm restent inchangés. [Politique, tests et limites](docs/flow-guard.fr.md).
@@ -108,14 +108,14 @@ Opérations limitées sur activation explicite : `node dist/mcp-server.js task`.
108
108
  "mcpServers": {
109
109
  "filesystem": {
110
110
  "command": "npx",
111
- "args": ["-y", "@aimarket/warden@0.22.4", "wrap", "--id", "filesystem", "--",
111
+ "args": ["-y", "@aimarket/warden@0.24.0", "wrap", "--id", "filesystem", "--",
112
112
  "npx", "-y", "@modelcontextprotocol/server-filesystem", "/Users/me/docs"]
113
113
  }
114
114
  }
115
115
  }
116
116
  ```
117
117
 
118
- Spécifiez toujours `--id` : sans cet identifiant, modifier les arguments crée une nouvelle identité et un premier contact. Un ID stable transforme un changement de commande ou de chemin en `SERVER_IDENTITY_DRIFT`. Le processus enfant hérite de l’environnement, exclu de l’identité. `npm install -g @aimarket/warden@0.22.4` puis `warden-mcp` évitent les démarrages à froid répétés de `npx`.
118
+ Spécifiez toujours `--id` : sans cet identifiant, modifier les arguments crée une nouvelle identité et un premier contact. Un ID stable transforme un changement de commande ou de chemin en `SERVER_IDENTITY_DRIFT`. Le processus enfant hérite de l’environnement, exclu de l’identité. `npm install -g @aimarket/warden@0.24.0` puis `warden-mcp` évitent les démarrages à froid répétés de `npx`.
119
119
 
120
120
  **Outils sensibles.** `sensitiveToolPatterns` dans un fichier de politique (`--policy policy.json` avec `{"sensitiveToolPatterns": ["*delete*", "*transfer*"]}`, motifs `*` insensibles à la casse) fait attendre une personne à chaque appel d’un outil correspondant : `wrap` demande par le formulaire du client lui-même (elicitation MCP), avec l’outil, le serveur et les arguments, et seule une réponse acceptée, case cochée, laisse passer cet appel-là. La case est décochée au départ : un client qui accepte les formulaires avec leurs valeurs par défaut n’approuve rien. Un client sans formulaire d’elicitation reçoit un refus et le serveur ne reçoit jamais l’appel ; `--ask refuse` refuse sans demander. Si le client annule l’appel pendant que la personne décide, ou si les définitions changent entre-temps, il n’est pas envoyé. Avant 0.20.0, `wrap` acceptait ces motifs sans les appliquer. Avec `--flow`, un envoi pour lequel la garde de flux demanderait est demandé de la même façon.
121
121
 
@@ -140,15 +140,24 @@ Claude Desktop sur macOS : `~/Library/Logs/Claude/mcp-server-<nom>.log`. Cursor
140
140
  | `--audit-only` | Mode diagnostic ; désactivé par défaut |
141
141
  | `--ask elicit\|refuse` | Un appel qui demande le oui d’une personne (outil sensible, question de la garde de flux) : `elicit` (par défaut) demande via le formulaire d’elicitation MCP du client et refuse s’il n’en a pas ; `refuse` refuse toujours |
142
142
 
143
+ ## Protéger un agent Codex
144
+
145
+ La même garde de flux pour OpenAI Codex (CLI, `codex exec`, application de bureau, runtimes Multica), à travers les
146
+ hooks de commande de Codex. Codex n’a pas de `ask` et laisse passer l’appel quand un hook échoue : l’adaptateur ne pose
147
+ donc jamais de question. Une question devient un refus ou un passage journalisé (`block: data|all`), et tout échec
148
+ refuse. Sur un hôte de runtime, installez-la en hooks gérés dans `/etc/codex/requirements.toml`. Les schémas pour
149
+ Multica et les limites sont dans [docs/codex.fr.md](docs/codex.fr.md) (red team dans le vocabulaire de Codex : `all`
150
+ 0 sur 28, `data` 3 sur 28, les mêmes trois qu’OpenCode). Code local, pas encore publié.
151
+
143
152
  ## Analyser tous les serveurs que démarrent vos clients
144
153
 
145
154
  ```bash
146
- npx -y @aimarket/warden@0.22.4 scan
155
+ npx -y @aimarket/warden@0.24.0 scan
147
156
  ```
148
157
 
149
158
  Lit les configurations MCP de Claude Code, Claude Desktop, Cursor, VS Code et Windsurf, se connecte à chaque serveur qu’elles démarrent et vérifie les définitions d’outils avant qu’un modèle ne les voie. Affiche un tableau, du JSON, du SARIF ou du Markdown, et sort avec 1 quand un serveur est bloqué ; `--no-launch` ne démarre rien. Dans un dépôt, `warden.lock.json` transforme un changement de définitions en diff relisible, et la CI échoue sur un serveur nouveau ou modifié. Existe aussi en GitHub Action (`uses: alexar76/warden@v0.21.0`), en hooks pre-commit et en plugin Claude Code (`/plugin marketplace add alexar76/warden`). `--histor` demande au journal public HISTOR si un serveur vous sert ce qu’il sert à tout le monde ; pour un serveur distant il envoie l’endpoint et un condensé, pour un serveur stdio lancé depuis npm ou PyPI le nom du paquet (`npm:<nom>`, `pypi:<nom>`, qu’HISTOR exécute dans un bac à sable gVisor) et un condensé — jamais le texte des outils. Un classificateur optionnel (`--classifier-url`, `--classifier-model`) ajoute la lecture d'un modèle que vous choisissez, local ou hébergé, pour ce qu'aucune règle ne nomme. Voir le [guide de scan](docs/scan.fr.md). Comment il se compare à deux autres scanners sur les mêmes serveurs : [comparaison de scanners](docs/scanner-comparison.fr.md).
150
159
 
151
- **Pour l’éditeur d’un serveur.** Si votre serveur liste d’autres outils là où est installé ce que le bac à sable d’HISTOR n’a pas — le runner d’un lanceur, un par système —, `npx -y @aimarket/warden@0.22.4 declare --out mcp-tool-sets.json -- <votre serveur>` écrit ces ensembles dans un fichier que vous publiez sur votre propre domaine, et ceux qui les reçoivent voient la déclaration de l’éditeur au lieu d’un ensemble inconnu. Voir le [guide de scan](docs/scan.fr.md).
160
+ **Pour l’éditeur d’un serveur.** Si votre serveur liste d’autres outils là où est installé ce que le bac à sable d’HISTOR n’a pas — le runner d’un lanceur, un par système —, `npx -y @aimarket/warden@0.24.0 declare --out mcp-tool-sets.json -- <votre serveur>` écrit ces ensembles dans un fichier que vous publiez sur votre propre domaine, et ceux qui les reçoivent voient la déclaration de l’éditeur au lieu d’un ensemble inconnu. Voir le [guide de scan](docs/scan.fr.md).
152
161
 
153
162
  ## Ce que WARDEN ne fait pas
154
163
 
@@ -345,6 +354,7 @@ transactions et la façon de les vérifier :
345
354
  | [Étude de terrain : 1 108 serveurs MCP publics](docs/mcp-survey.fr.md) | Ce que WARDEN a décidé sur de vraies définitions d'outil tierces — 50 serveurs bloqués, 4 étayés, et les six façons dont le reste était faux |
346
355
  | [Comparaison de scanners](docs/scanner-comparison.fr.md) | WARDEN, mcp-audit, mcp-shield, truecopy et mcpsentry sur les mêmes serveurs, sur 14 933 paquets npm et PyPI et sur le benchmark MCPTox, avec chaque jugement, le manifeste et le banc d’essai |
347
356
  | [Garde de flux](docs/flow-guard.fr.md) | La protection à l’exécution du plugin Claude Code : texte extérieur, données privées, appels sortants ; la mesure sur AgentDojo et ses limites |
357
+ | [Garde de flux pour Codex](docs/codex.fr.md) | Hooks Codex : pas de `ask`, échec fermé, hooks gérés, schémas pour Multica |
348
358
  | [Nouvelle comparaison du modèle](docs/flow-guard-model-comparison-2026-10-25.fr.md) | 720 réponses : amélioration sur des cas connus, incertitude, canal d’avertissement et aucune correction d’ID observée par Stop |
349
359
  | [Glama / Docker](docs/GLAMA.md) | MCP stdio, health check, Build steps / CMD |
350
360
  | [Security](SECURITY.md) | Signaler un contournement du pare-feu |
@@ -369,7 +379,7 @@ transactions et la façon de les vérifier :
369
379
  ## Développement
370
380
 
371
381
  ```bash
372
- npm install && npm run build && npm test # 1400 tests
382
+ npm install && npm run build && npm test # 1517 tests
373
383
  ```
374
384
 
375
385
  `test/packaging.test.ts` est ce qui tient l'accroche honnête : il échoue si une dépendance d'exécution
package/README-ru.md CHANGED
@@ -12,7 +12,7 @@
12
12
  <a href="https://glama.ai/mcp/servers/alexar76/warden"><img src="https://glama.ai/mcp/servers/alexar76/warden/badges/score.svg" alt="warden MCP server" /></a>
13
13
  <a href="https://warden.modelmarket.dev/"><img src="https://img.shields.io/npm/v/@aimarket/warden?color=cb3837&label=npm" alt="npm version" /></a>
14
14
  <img src="docs/badges/deps.svg" alt="Zero runtime dependencies" />
15
- <img src="docs/badges/tests.svg" alt="1400 tests passing" />
15
+ <img src="docs/badges/tests.svg" alt="1517 tests passing" />
16
16
  <img src="docs/badges/node.svg" alt="Node >= 20" />
17
17
  <a href="LICENSE"><img src="docs/badges/license.svg" alt="License: MIT" /></a>
18
18
  </p>
@@ -33,11 +33,11 @@
33
33
  **Проверьте все MCP-серверы на своей машине.** Без аккаунта, без API-ключа, без модели. Сетевой трафик идёт только к серверам из вашего конфига.
34
34
 
35
35
  ```bash
36
- npx -y @aimarket/warden@0.22.4 scan
36
+ npx -y @aimarket/warden@0.24.0 scan
37
37
  ```
38
38
 
39
39
  ```text
40
- WARDEN scan 0.22.4 · ruleset 17 sha256-UOfK25xo6D8v… · block at high
40
+ WARDEN scan 0.24.0 · ruleset 17 sha256-UOfK25xo6D8v… · block at high
41
41
  read .mcp.json (claude-code, 3 servers)
42
42
 
43
43
  ✓ allow notes claude-code 1 tool · score 0.90
@@ -48,7 +48,7 @@ WARDEN scan 0.22.4 · ruleset 17 sha256-UOfK25xo6D8v… · block at high
48
48
  Details: warden-mcp scan --json, or --markdown FILE. To review a changed server: warden-mcp scan --lock warden.lock.json --update-lock.
49
49
  ```
50
50
 
51
- Рядом с четырьмя другими открытыми сканерами на одних и тех же серверах, каждый в контейнере gVisor без сети: на отложенной половине MCPTox (бенчмарк AAAI 2026; правила WARDEN писались по другой половине) WARDEN блокирует 171 отравленный инструмент из 218, остальные — от 8 до 41. На 986 публичных серверах WARDEN блокирует 3, на 14 933 пакетах npm и PyPI — 369; mcp-shield — 343 и 5 354. [Методика и все цифры](docs/scanner-comparison.ru.md) · [руководство по scan](docs/scan.ru.md).
51
+ Рядом с четырьмя другими открытыми сканерами на одних и тех же серверах, каждый в контейнере gVisor без сети: на отложенной половине MCPTox (бенчмарк AAAI 2026; правила WARDEN писались по другой половине) WARDEN блокировал 171 отравленный инструмент из 218 с правилами того сравнения (v12), а начиная с ruleset v16 блокирует 210; остальные — от 8 до 41. На 986 публичных серверах WARDEN блокирует 3, на 14 933 пакетах npm и PyPI — 369; mcp-shield — 343 и 5 354. [Методика и все цифры](docs/scanner-comparison.ru.md) · [руководство по scan](docs/scan.ru.md).
52
52
  <!-- /warden-try -->
53
53
 
54
54
  **Страж потоков (локальный код, 2026-10-23).** После учётных данных и внешнего текста исходящие/MCP-вызовы и обычные записи в проект требуют проверки независимо от длины фрагмента и неизвестной кодировки. Точные публичные запросы, проверенные оператором, могут исполняться один раз за сессию; найденные утечки и неполная проверка этим не освобождаются. В тестовом сценарии автоматически прошло 0/16 атак в обоих режимах; подтверждение для безвредных вызовов — 12/12 по умолчанию, 0/12 с точными правилами. Это явный компромисс удобства, а не универсальный декодер. Прежний набор — 0/23 прошедших целиком. Прод и npm не обновлены. [Политика, тесты и пределы](docs/flow-guard.ru.md).
@@ -108,7 +108,7 @@ MCP-сервер добавляет другие `node:` builtins (`fs`, `path`,
108
108
  "mcpServers": {
109
109
  "filesystem": {
110
110
  "command": "npx",
111
- "args": ["-y", "@aimarket/warden@0.22.4", "wrap", "--id", "filesystem", "--",
111
+ "args": ["-y", "@aimarket/warden@0.24.0", "wrap", "--id", "filesystem", "--",
112
112
  "npx", "-y", "@modelcontextprotocol/server-filesystem", "/Users/me/docs"]
113
113
  }
114
114
  }
@@ -117,7 +117,7 @@ MCP-сервер добавляет другие `node:` builtins (`fs`, `path`,
117
117
 
118
118
  Для обязательного утверждения первого контакта добавьте к `wrap` флаг `--require-approval`. Определения не попадут модели до `warden-mcp pins approve --id filesystem` в терминале оператора. Любое изменение полей или идентичности запуска требует нового утверждения; автоматические и старые pins не подходят. Подробнее: [граница допуска, не зависящая от языка](docs/security-hardening-language-boundary.md).
119
119
 
120
- Всегда задавайте `--id`: без него изменение аргументов создаёт новую идентичность и новый первый контакт. Со стабильным ID смена команды или пути даёт `SERVER_IDENTITY_DRIFT`. Дочерний процесс наследует окружение; оно не входит в идентичность. Чтобы избежать холодного старта `npx`, установите глобально: `npm install -g @aimarket/warden@0.22.4`, затем команда `warden-mcp`.
120
+ Всегда задавайте `--id`: без него изменение аргументов создаёт новую идентичность и новый первый контакт. Со стабильным ID смена команды или пути даёт `SERVER_IDENTITY_DRIFT`. Дочерний процесс наследует окружение; оно не входит в идентичность. Чтобы избежать холодного старта `npx`, установите глобально: `npm install -g @aimarket/warden@0.24.0`, затем команда `warden-mcp`.
121
121
 
122
122
  **Чувствительные инструменты.** `sensitiveToolPatterns` в файле политики (`--policy policy.json` с `{"sensitiveToolPatterns": ["*delete*", "*transfer*"]}`, шаблоны `*` без учёта регистра) заставляет каждый вызов подходящего инструмента ждать человека: `wrap` спрашивает через собственную форму клиента (MCP elicitation), показывая инструмент, сервер и аргументы, и пропускает этот один вызов только при отмеченной галочке и принятой форме. Галочка по умолчанию снята, поэтому клиент, принимающий формы со значениями по умолчанию, ничего не одобрит. Клиенту без формы elicitation вызов отклоняется, и сервер его не получает; `--ask refuse` отклоняет, не спрашивая. Если клиент отменил вызов, пока человек решает, или за это время изменились определения, вызов не отправляется. До 0.20.0 `wrap` принимал эти шаблоны, но не применял их. С `--flow` отправка, о которой страж потоков спросил бы, спрашивается так же.
123
123
 
@@ -142,15 +142,24 @@ warden-mcp pins revoke --id filesystem
142
142
  | `--audit-only` | Диагностический режим; по умолчанию выключен |
143
143
  | `--ask elicit\|refuse` | Вызов, которому нужно «да» человека (чувствительный инструмент, вопрос стража потоков): `elicit` (по умолчанию) спрашивает через форму MCP elicitation клиента и отклоняет, если её нет; `refuse` всегда отклоняет |
144
144
 
145
+ ## Защитить агента на Codex
146
+
147
+ Тот же страж потоков для OpenAI Codex (CLI, `codex exec`, приложение, исполнители Multica) через командные хуки Codex.
148
+ У Codex нет `ask`, а при сбое хука вызов выполняется, поэтому адаптер никогда не спрашивает: вопрос становится отказом
149
+ или пропуском с записью в лог (`block: data|all`), а любой сбой даёт отказ. На сервере исполнителя ставьте его как
150
+ managed-хуки в `/etc/codex/requirements.toml`. Схемы развёртывания в Multica и ограничения — в
151
+ [docs/codex.ru.md](docs/codex.ru.md) (red-team в словаре инструментов Codex: `all` 0 из 28, `data` 3 из 28, те же три,
152
+ что у OpenCode). Локальный код, ещё не выпущен.
153
+
145
154
  ## Проверить все серверы, которые запускают ваши клиенты
146
155
 
147
156
  ```bash
148
- npx -y @aimarket/warden@0.22.4 scan
157
+ npx -y @aimarket/warden@0.24.0 scan
149
158
  ```
150
159
 
151
160
  Читает MCP-конфиги Claude Code, Claude Desktop, Cursor, VS Code и Windsurf, подключается к каждому серверу из них и проверяет определения инструментов до того, как их увидит модель. Выводит таблицу, JSON, SARIF или Markdown и завершается с кодом 1, если сервер заблокирован; `--no-launch` ничего не запускает. В репозитории `warden.lock.json` превращает изменение определений инструментов в дифф для ревью, а CI падает на новом или изменённом сервере. Есть GitHub Action (`uses: alexar76/warden@v0.21.0`), хуки pre-commit и плагин Claude Code (`/plugin marketplace add alexar76/warden`). `--histor` спрашивает публичный журнал HISTOR, отдаёт ли сервер вам то же, что всем; для удалённого сервера уходят адрес и дайджест, для stdio-сервера из npm или PyPI — имя пакета (`npm:<имя>`, `pypi:<имя>`; HISTOR запускает такие пакеты в песочнице gVisor) и дайджест, текст инструментов — никогда. Опциональный классификатор (`--classifier-url`, `--classifier-model`) добавляет прочтение модели, которую выбираете вы, локальной или облачной, — для того, что не называет ни одно правило. Подробно — в [руководстве по scan](docs/scan.ru.md). Как он выглядит рядом с двумя другими сканерами на одних и тех же серверах: [сравнение сканеров](docs/scanner-comparison.ru.md).
152
161
 
153
- **Для издателя сервера.** Если ваш сервер отдаёт другие инструменты там, где установлено то, чего нет в песочнице HISTOR, — раннер запускателя, по одному на ОС, — `npx -y @aimarket/warden@0.22.4 declare --out mcp-tool-sets.json -- <ваш сервер>` записывает эти наборы в файл, который вы публикуете на своём домене, и те, кто их получает, видят заявление издателя, а не незнакомый набор. Подробно — в [руководстве по scan](docs/scan.ru.md).
162
+ **Для издателя сервера.** Если ваш сервер отдаёт другие инструменты там, где установлено то, чего нет в песочнице HISTOR, — раннер запускателя, по одному на ОС, — `npx -y @aimarket/warden@0.24.0 declare --out mcp-tool-sets.json -- <ваш сервер>` записывает эти наборы в файл, который вы публикуете на своём домене, и те, кто их получает, видят заявление издателя, а не незнакомый набор. Подробно — в [руководстве по scan](docs/scan.ru.md).
154
163
 
155
164
  ## Чего WARDEN не делает
156
165
 
@@ -346,6 +355,7 @@ WARDEN — агент ERC-8004 [`96684` в сети Base](https://8004scan.io/ag
346
355
  | [Полевой обзор: 1 108 публичных MCP-серверов](docs/mcp-survey.ru.md) | Что WARDEN решил на настоящих чужих определениях инструментов — 50 серверов заблокировано, 4 подтверждено, и шесть способов, которыми остальные оказались ошибкой |
347
356
  | [Сравнение сканеров](docs/scanner-comparison.ru.md) | WARDEN, mcp-audit, mcp-shield, truecopy и mcpsentry на одних и тех же серверах, на 14 933 пакетах npm и PyPI и на бенчмарке MCPTox, со всеми разметками, манифестом и стендом |
348
357
  | [Страж потоков](docs/flow-guard.ru.md) | Защита плагина Claude Code во время работы: чужой текст, приватные данные, исходящие вызовы; измерение на AgentDojo и его границы |
358
+ | [Страж потоков для Codex](docs/codex.ru.md) | Хуки Codex: без `ask`, отказ при сбое, managed-хуки, схемы для Multica |
349
359
  | [Свежий прогон модели](docs/flow-guard-model-comparison-2026-10-25.ru.md) | 720 ответов: улучшение на известных сценариях, неопределённость, канал предупреждений и отсутствие исправленных ID через Stop |
350
360
  | [Glama / Docker](docs/GLAMA.md) | stdio MCP, health check, Build steps / CMD |
351
361
  | [Security](SECURITY.md) | Как сообщать об обходе файрвола |
@@ -370,7 +380,7 @@ WARDEN — агент ERC-8004 [`96684` в сети Base](https://8004scan.io/ag
370
380
  ## Разработка
371
381
 
372
382
  ```bash
373
- npm install && npm run build && npm test # 1400 тестов
383
+ npm install && npm run build && npm test # 1517 тестов
374
384
  ```
375
385
 
376
386
  `test/packaging.test.ts` — то, что удерживает заголовок честным: он падает, если появляется
package/README-zh.md CHANGED
@@ -12,7 +12,7 @@
12
12
  <a href="https://glama.ai/mcp/servers/alexar76/warden"><img src="https://glama.ai/mcp/servers/alexar76/warden/badges/score.svg" alt="warden MCP server" /></a>
13
13
  <a href="https://warden.modelmarket.dev/"><img src="https://img.shields.io/npm/v/@aimarket/warden?color=cb3837&label=npm" alt="npm 版本" /></a>
14
14
  <img src="docs/badges/deps.svg" alt="零运行时依赖" />
15
- <img src="docs/badges/tests.svg" alt="1400 项测试通过" />
15
+ <img src="docs/badges/tests.svg" alt="1517 项测试通过" />
16
16
  <img src="docs/badges/node.svg" alt="Node >= 20" />
17
17
  <a href="LICENSE"><img src="docs/badges/license.svg" alt="许可证:MIT" /></a>
18
18
  </p>
@@ -33,11 +33,11 @@
33
33
  **检查你机器上的所有 MCP 服务器。** 无需账号、无需 API 密钥、不调用模型。唯一的网络流量是发往你配置中的服务器。
34
34
 
35
35
  ```bash
36
- npx -y @aimarket/warden@0.22.4 scan
36
+ npx -y @aimarket/warden@0.24.0 scan
37
37
  ```
38
38
 
39
39
  ```text
40
- WARDEN scan 0.22.4 · ruleset 17 sha256-UOfK25xo6D8v… · block at high
40
+ WARDEN scan 0.24.0 · ruleset 17 sha256-UOfK25xo6D8v… · block at high
41
41
  read .mcp.json (claude-code, 3 servers)
42
42
 
43
43
  ✓ allow notes claude-code 1 tool · score 0.90
@@ -48,7 +48,7 @@ WARDEN scan 0.22.4 · ruleset 17 sha256-UOfK25xo6D8v… · block at high
48
48
  Details: warden-mcp scan --json, or --markdown FILE. To review a changed server: warden-mcp scan --lock warden.lock.json --update-lock.
49
49
  ```
50
50
 
51
- 与另外四款开源扫描器在同一批服务器上对比,每款都在无网络的 gVisor 容器中运行:在 MCPTox(AAAI 2026 基准)的留出一半上(WARDEN 的规则只依据另一半编写),WARDEN 阻止了 218 个投毒工具中的 171 个,其余扫描器阻止 8 到 41 个。在 986 台公开服务器上 WARDEN 阻止 3 台,在 14,933 个 npm 和 PyPI 包上阻止 369 个;mcp-shield 分别阻止 343 台和 5,354 个。[方法与全部数字](docs/scanner-comparison.zh.md) · [scan 指南](docs/scan.zh.md)。
51
+ 与另外四款开源扫描器在同一批服务器上对比,每款都在无网络的 gVisor 容器中运行:在 MCPTox(AAAI 2026 基准)的留出一半上(WARDEN 的规则只依据另一半编写),按该次对比时的规则(v12),WARDEN 阻止了 218 个投毒工具中的 171 个,自 ruleset v16 起阻止 210 个;其余扫描器阻止 8 到 41 个。在 986 台公开服务器上 WARDEN 阻止 3 台,在 14,933 个 npm 和 PyPI 包上阻止 369 个;mcp-shield 分别阻止 343 台和 5,354 个。[方法与全部数字](docs/scanner-comparison.zh.md) · [scan 指南](docs/scan.zh.md)。
52
52
  <!-- /warden-try -->
53
53
 
54
54
  **流守卫(2026-10-23 本地源码)。** 读取凭据和外部文本后,传出/MCP 调用及普通项目写入均需审核,即使片段极短或编码未知。操作员检查过的精确公开请求可每会话自动执行一次,但不能豁免已识别泄露或不完整扫描。测试中两种配置均自动放行 0/16 攻击;正常请求默认确认 12/12,精确规则下 0/12。这是明确的可用性取舍,不是万能解码器。同一旧案例集仍为 0/23 完整通过。生产和 npm 未更改。[策略、测试与边界](docs/flow-guard.zh.md)。
@@ -104,14 +104,14 @@ Auten 后续:`taskAdapter.mode: "review"` / `task_run` 按固定结果确认
104
104
  "mcpServers": {
105
105
  "filesystem": {
106
106
  "command": "npx",
107
- "args": ["-y", "@aimarket/warden@0.22.4", "wrap", "--id", "filesystem", "--",
107
+ "args": ["-y", "@aimarket/warden@0.24.0", "wrap", "--id", "filesystem", "--",
108
108
  "npx", "-y", "@modelcontextprotocol/server-filesystem", "/Users/me/docs"]
109
109
  }
110
110
  }
111
111
  }
112
112
  ```
113
113
 
114
- 始终指定 `--id`:否则修改命令参数会创建新身份并重新执行首次信任。稳定 ID 会把命令或路径变更识别为 `SERVER_IDENTITY_DRIFT`。子进程继承环境变量,身份哈希不包含环境。可运行 `npm install -g @aimarket/warden@0.22.4`,使用 `warden-mcp` 避免反复进行 `npx` 冷启动。
114
+ 始终指定 `--id`:否则修改命令参数会创建新身份并重新执行首次信任。稳定 ID 会把命令或路径变更识别为 `SERVER_IDENTITY_DRIFT`。子进程继承环境变量,身份哈希不包含环境。可运行 `npm install -g @aimarket/warden@0.24.0`,使用 `warden-mcp` 避免反复进行 `npx` 冷启动。
115
115
 
116
116
  **敏感工具。** 策略文件中的 `sensitiveToolPatterns`(`--policy policy.json`,内容如 `{"sensitiveToolPatterns": ["*delete*", "*transfer*"]}`,`*` 通配、不区分大小写)让每次调用匹配的工具都要等人确认:`wrap` 通过客户端自己的表单(MCP elicitation)询问,列出工具、服务器和参数,只有勾选并接受的回答才放行这一次调用。复选框默认不勾选,所以按默认值自动接受表单的客户端什么也批准不了。不提供 elicitation 表单的客户端会收到拒绝,服务器永远收不到这次调用;`--ask refuse` 不询问直接拒绝。若客户端在等人决定时取消调用,或其间定义发生变化,调用不会发出。0.20.0 之前 `wrap` 接受这些模式却不执行。配合 `--flow`,流守卫会询问的发送也以同样方式询问。
117
117
 
@@ -136,15 +136,23 @@ macOS 上 Claude Desktop 日志:`~/Library/Logs/Claude/mcp-server-<名称>.log
136
136
  | `--audit-only` | 诊断模式;默认关闭 |
137
137
  | `--ask elicit\|refuse` | 需要人确认的调用(敏感工具、流守卫的询问):`elicit`(默认)通过客户端的 MCP elicitation 表单询问,客户端没有表单时拒绝;`refuse` 总是拒绝 |
138
138
 
139
+ ## 保护 Codex 智能体
140
+
141
+ 同一个流守卫,通过 Codex 的命令钩子用于 OpenAI Codex(CLI、`codex exec`、桌面应用、Multica 运行时)。Codex 没有
142
+ `ask`,钩子失败时会照常执行调用,因此适配器从不询问:询问会变成拒绝或记录在案的放行(`block: data|all`),任何失败
143
+ 都会拒绝。在运行时主机上,请把它作为托管钩子安装在 `/etc/codex/requirements.toml` 中。Multica 部署方式和局限见
144
+ [docs/codex.zh.md](docs/codex.zh.md)(用 Codex 工具词汇重放红队:`all` 28 个中 0 个,`data` 28 个中 3 个,与 OpenCode
145
+ 相同的三个)。本地源码,尚未发布。
146
+
139
147
  ## 扫描客户端启动的所有服务器
140
148
 
141
149
  ```bash
142
- npx -y @aimarket/warden@0.22.4 scan
150
+ npx -y @aimarket/warden@0.24.0 scan
143
151
  ```
144
152
 
145
153
  读取 Claude Code、Claude Desktop、Cursor、VS Code 和 Windsurf 的 MCP 配置,连接其中启动的每个服务器,并在模型看到工具定义之前对其进行审查。输出表格、JSON、SARIF 或 Markdown,有服务器被阻止时以 1 退出;`--no-launch` 不启动任何程序。在仓库中,`warden.lock.json` 把工具定义的改动变成可审查的 diff,CI 会在出现新的或改动过的服务器时失败。也提供 GitHub Action(`uses: alexar76/warden@v0.21.0`)、pre-commit 钩子和 Claude Code 插件(`/plugin marketplace add alexar76/warden`)。`--histor` 询问公开的 HISTOR 日志:服务器给你的是否与给所有人的相同;对远程服务器发送端点和摘要,对从 npm 或 PyPI 启动的 stdio 服务器发送软件包名(`npm:<名称>`、`pypi:<名称>`,HISTOR 会在 gVisor 沙箱中运行它)和摘要,从不发送工具文本。可选的分类器(`--classifier-url`、`--classifier-model`)会加入你所选模型(本地或托管)的判断,用于覆盖任何规则都没有提到的内容。详见 [scan 指南](docs/scan.zh.md)。与另外两款扫描器在同一批服务器上的对比,见[扫描器对比](docs/scanner-comparison.zh.md)。
146
154
 
147
- **面向服务器发布者。** 如果在安装了 HISTOR 沙箱所没有的东西(启动器的运行器、每个操作系统各一个)的地方,你的服务器列出的是别的工具,`npx -y @aimarket/warden@0.22.4 declare --out mcp-tool-sets.json -- <你的服务器>` 会把这些工具集写进一个文件,由你发布在自己的域名上;拿到这些工具集的人看到的将是发布者的声明,而不是陌生的工具集。参见 [scan 指南](docs/scan.zh.md)。
155
+ **面向服务器发布者。** 如果在安装了 HISTOR 沙箱所没有的东西(启动器的运行器、每个操作系统各一个)的地方,你的服务器列出的是别的工具,`npx -y @aimarket/warden@0.24.0 declare --out mcp-tool-sets.json -- <你的服务器>` 会把这些工具集写进一个文件,由你发布在自己的域名上;拿到这些工具集的人看到的将是发布者的声明,而不是陌生的工具集。参见 [scan 指南](docs/scan.zh.md)。
148
156
 
149
157
  ## WARDEN 不做什么
150
158
 
@@ -326,6 +334,7 @@ WARDEN 是 [Base 上的 `96684` 号](https://8004scan.io/agents/base/96684) ERC-
326
334
  | [实地普查:1 108 个公开 MCP 服务器](docs/mcp-survey.zh.md) | WARDEN 在真实的第三方工具定义上判了什么——拦截 50 个服务器,4 项成立,其余判错的六种方式 |
327
335
  | [扫描器对比](docs/scanner-comparison.zh.md) | WARDEN、mcp-audit、mcp-shield、truecopy 与 mcpsentry 在同一批服务器、14,933 个 npm 和 PyPI 包以及 MCPTox 基准上的结果,附全部判定、清单和测试工具 |
328
336
  | [流向守卫](docs/flow-guard.zh.md) | Claude Code 插件的运行时守卫:外部文本、私有数据、外发调用;AgentDojo 测量及其局限 |
337
+ | [Codex 的流守卫](docs/codex.zh.md) | Codex 钩子:没有 `ask`、失败即拒绝、托管钩子、Multica 部署方式 |
329
338
  | [新的模型对比](docs/flow-guard-model-comparison-2026-10-25.zh.md) | 720 个答案:已知案例上的改善、不确定性、警告内容边界,以及未观察到 Stop 纠正 ID |
330
339
  | [Glama / Docker](docs/GLAMA.md) | stdio MCP、健康检查、Build steps / CMD |
331
340
  | [Security](SECURITY.md) | 如何报告防火墙绕过 |
@@ -346,7 +355,7 @@ WARDEN 是 [Base 上的 `96684` 号](https://8004scan.io/agents/base/96684) ERC-
346
355
  ## 开发
347
356
 
348
357
  ```bash
349
- npm install && npm run build && npm test # 1400 项测试
358
+ npm install && npm run build && npm test # 1517 项测试
350
359
  ```
351
360
 
352
361
  `test/packaging.test.ts` 正是让标题保持诚实的东西:一旦出现运行时依赖、任何源文件从包外 import、或者入口点不
package/README.md CHANGED
@@ -6,11 +6,11 @@ Vets what an MCP server *says* its tools do — tool poisoning, rug pulls, reque
6
6
  **Check every MCP server on your machine.** No account, no API key, no model. `scan` starts each server in your config the way your client would, reads its `tools/list`, vets it and stops it; the only network traffic is to those servers.
7
7
 
8
8
  ```bash
9
- npx -y @aimarket/warden@0.22.4 scan
9
+ npx -y @aimarket/warden@0.24.0 scan
10
10
  ```
11
11
 
12
12
  ```text
13
- WARDEN scan 0.22.4 · ruleset 17 sha256-UOfK25xo6D8v… · block at high
13
+ WARDEN scan 0.24.0 · ruleset 17 sha256-UOfK25xo6D8v… · block at high
14
14
  read .mcp.json (claude-code, 3 servers)
15
15
 
16
16
  ✓ allow notes claude-code 1 tool · score 0.90
@@ -23,9 +23,9 @@ WARDEN scan 0.22.4 · ruleset 17 sha256-UOfK25xo6D8v… · block at high
23
23
  Details: warden-mcp scan --json, or --markdown FILE. To review a changed server: warden-mcp scan --lock warden.lock.json --update-lock.
24
24
  ```
25
25
 
26
- That is the real output of 0.22.4 on [`examples/scan-demo/`](examples/scan-demo/): three tiny stdio servers, one of them poisoned. `cd examples/scan-demo && npx -y @aimarket/warden@0.22.4 scan --project` reproduces it with nothing installed. [Scan guide](docs/scan.md).
26
+ That is the real output of 0.24.0 on [`examples/scan-demo/`](examples/scan-demo/): three tiny stdio servers, one of them poisoned. `cd examples/scan-demo && npx -y @aimarket/warden@0.24.0 scan --project` reproduces it with nothing installed. [Scan guide](docs/scan.md).
27
27
 
28
- Against four other open-source scanners on the same servers, each in a gVisor container with no network: on the held-out half of MCPTox (an AAAI 2026 benchmark; WARDEN's rules were written from the other half) WARDEN blocks 171 of 218 poisoned tools, the others 8 to 41. On 986 public servers it blocks 3 and on 14,933 npm and PyPI packages 369; mcp-shield blocks 343 and 5,354. [Method and every number](docs/scanner-comparison.md) · [scan guide](docs/scan.md) · **[for teams: one policy, a lock per repository, weekly checks](docs/teams.md)**.
28
+ Against four other open-source scanners on the same servers, each in a gVisor container with no network: on the held-out half of MCPTox (an AAAI 2026 benchmark; WARDEN's rules were written from the other half) WARDEN blocked 171 of 218 poisoned tools with the rules of that comparison (v12) and blocks 210 since ruleset v16, the others 8 to 41. On 986 public servers it blocks 3 and on 14,933 npm and PyPI packages 369; mcp-shield blocks 343 and 5,354. [Method and every number](docs/scanner-comparison.md) · [scan guide](docs/scan.md) · **[for teams: one policy, a lock per repository, weekly checks](docs/teams.md)**.
29
29
  <!-- /warden-try -->
30
30
 
31
31
  <!-- mcp-name: io.github.alexar76/warden -->
@@ -36,7 +36,7 @@ Against four other open-source scanners on the same servers, each in a gVisor co
36
36
  <a href="https://glama.ai/mcp/servers/alexar76/warden"><img src="https://glama.ai/mcp/servers/alexar76/warden/badges/score.svg" alt="warden MCP server" /></a>
37
37
  <a href="https://warden.modelmarket.dev/"><img src="https://img.shields.io/npm/v/@aimarket/warden?color=cb3837&label=npm" alt="npm version" /></a>
38
38
  <img src="docs/badges/deps.svg" alt="Zero runtime dependencies" />
39
- <img src="docs/badges/tests.svg" alt="1400 tests passing" />
39
+ <img src="docs/badges/tests.svg" alt="1517 tests passing" />
40
40
  <img src="docs/badges/node.svg" alt="Node >= 20" />
41
41
  <a href="LICENSE"><img src="docs/badges/license.svg" alt="License: MIT" /></a>
42
42
  </p>
@@ -60,7 +60,7 @@ Against four other open-source scanners on the same servers, each in a gVisor co
60
60
  **Flow guard (local source, 2026-10-23).** After credentials and outside text, outbound/MCP calls and ordinary project writes require review, regardless of short fragments or unknown encodings. Exact operator-reviewed public requests can run once per session; known leaks and incomplete scans stay blocked from this exemption. Fixture: 0/16 attacks automatically allowed in both modes; 12/12 benign calls reviewed by default, 0/12 with exact public rules. This is an explicit usability tradeoff, not universal decoding. The unchanged 23-case replay remains 0/23 fully delivered. Production/npm are unchanged. [Policy, tests and limits](docs/flow-guard.md).
61
61
 
62
62
 
63
- Ruleset v16 (0.20.0, 2026-10-22, WARDEN only): MCPTox held-out half 210 of 218 (v15: 194, v12–v14: 171), 0 of 45 clean servers; on the field corpus and a 1,000-package HISTOR sample it blocks exactly what v15 blocked. Ruleset v17 (0.22.4, 2026-11-01) adds a case from outside MCPTox, a tool that adds a BCC to another server's `send_email`, and changes no verdict on any of these sets. The comparison with other scanners above is from 2026-10-16 with v12. [v15 and v16 in the gate chain](docs/gates.md).
63
+ Ruleset v16 (0.20.0, 2026-10-22, WARDEN only): MCPTox held-out half 210 of 218 (v15: 194, v12–v14: 171), 0 of 45 clean servers; on the field corpus and a 1,000-package HISTOR sample it blocks exactly what v15 blocked. Ruleset v17 (0.23.0, 2026-11-01) adds a case from outside MCPTox, a tool that adds a BCC to another server's `send_email`, and changes no verdict on any of these sets. The comparison with other scanners above is from 2026-10-16 with v12. [v15 and v16 in the gate chain](docs/gates.md).
64
64
 
65
65
  > [0.7.0 security changes and migration](docs/security-hardening.md): `vetLaunch`, durable pins, anti-rollback, ruleset v6, runtime revalidation.
66
66
 
@@ -113,7 +113,7 @@ Opt-in constrained operations: `node dist/mcp-server.js task`. See the [task ada
113
113
  "mcpServers": {
114
114
  "filesystem": {
115
115
  "command": "npx",
116
- "args": ["-y", "@aimarket/warden@0.22.4", "wrap", "--id", "filesystem", "--",
116
+ "args": ["-y", "@aimarket/warden@0.24.0", "wrap", "--id", "filesystem", "--",
117
117
  "npx", "-y", "@modelcontextprotocol/server-filesystem", "/Users/me/docs"]
118
118
  }
119
119
  }
@@ -122,7 +122,7 @@ Opt-in constrained operations: `node dist/mcp-server.js task`. See the [task ada
122
122
 
123
123
  For explicit first-contact review, add `--require-approval` to `wrap`. It withholds new definitions until `warden-mcp pins approve --id filesystem` in an operator terminal, then rejects any changed field or launch identity. Automatic/legacy pins need reapproval. See the [language-independent admission boundary](docs/security-hardening-language-boundary.md).
124
124
 
125
- Always specify `--id`: without it, changing command arguments creates a new identity and a new first contact. A stable ID turns a command or path change into `SERVER_IDENTITY_DRIFT`. Environment variables are inherited by the child and excluded from identity. To avoid repeated cold `npx` starts, install globally with `npm install -g @aimarket/warden@0.22.4`, then use `warden-mcp`.
125
+ Always specify `--id`: without it, changing command arguments creates a new identity and a new first contact. A stable ID turns a command or path change into `SERVER_IDENTITY_DRIFT`. Environment variables are inherited by the child and excluded from identity. To avoid repeated cold `npx` starts, install globally with `npm install -g @aimarket/warden@0.24.0`, then use `warden-mcp`.
126
126
 
127
127
  **Sensitive tools.** A policy file's `sensitiveToolPatterns` (`--policy policy.json` with `{"sensitiveToolPatterns": ["*delete*", "*transfer*"]}`, case-insensitive `*` globs) makes every call to a matching tool wait for a person: `wrap` asks through the client's own form (MCP elicitation) with the tool, the server and the arguments, and only a ticked, accepted answer lets that one call through. The box starts unticked, so a client that accepts forms with their defaults approves nothing. A client that offers no elicitation form gets a refusal and the server never receives the call; `--ask refuse` refuses without asking. If the client cancels the call while the person decides, or the definitions change meanwhile, it is not sent. Before 0.20.0 `wrap` accepted these patterns and did not enforce them. With `--flow`, a send the flow guard would ask about is asked the same way.
128
128
 
@@ -147,15 +147,32 @@ Claude Desktop on macOS writes stderr to `~/Library/Logs/Claude/mcp-server-<name
147
147
  | `--audit-only` | Diagnostic mode; off by default |
148
148
  | `--ask elicit\|refuse` | A call that needs a person's yes (a sensitive tool, a flow-guard question): `elicit` (default) asks through the client's MCP elicitation form and refuses when the client has none; `refuse` always refuses |
149
149
 
150
+ ## Guard an OpenCode agent
151
+
152
+ The same flow guard as the Claude Code plugin, as an OpenCode plugin for agents that run unattended (Multica, CI,
153
+ cron): calls that would carry data the session read after outside text are refused, a known secret is denied,
154
+ OpenCode's own config is protected, and `shell.env` blanks keys shell commands do not need. See
155
+ [docs/opencode.md](docs/opencode.md) for the `block` modes and what each lets through (red-team replay: `all` 0 of
156
+ 28, `data` 3 of 28, all three action-only).
157
+
158
+ ## Guard a Codex agent
159
+
160
+ The same flow guard for OpenAI Codex (CLI, `codex exec`, desktop app, Multica runtimes), through Codex's command hooks.
161
+ Codex has no `ask` and runs the call when a hook fails, so the adapter never asks: a question becomes a refusal or a
162
+ logged pass (`block: data|all`), and every failure denies. Install it as managed hooks in `/etc/codex/requirements.toml`
163
+ on a runtime host. See [docs/codex.md](docs/codex.md) for the Multica deployment schemes and the limits (red-team
164
+ replay in Codex's tool vocabulary: `all` 0 of 28, `data` 3 of 28, the same three as OpenCode). Local source, not
165
+ released yet.
166
+
150
167
  ## Scan every server your clients start
151
168
 
152
169
  ```bash
153
- npx -y @aimarket/warden@0.22.4 scan
170
+ npx -y @aimarket/warden@0.24.0 scan
154
171
  ```
155
172
 
156
173
  Reads the MCP configs of Claude Code, Claude Desktop, Cursor, VS Code and Windsurf, connects to every server they start, and vets the tool definitions before a model sees them. It prints a table, JSON, SARIF or Markdown, and exits 1 when a server is blocked; `--no-launch` starts nothing. In a repository, `warden.lock.json` turns a change in tool definitions into a reviewable diff, and CI fails on a new or changed server. Also as a GitHub Action (`uses: alexar76/warden@v0.21.0`), pre-commit hooks and a Claude Code plugin (`/plugin marketplace add alexar76/warden`). `--histor` asks the public HISTOR log whether a server serves you what it serves everyone; for a remote server it sends the endpoint and a digest, for a stdio server started from npm or PyPI the package name (`npm:<name>`, `pypi:<name>`, which HISTOR runs in a gVisor sandbox) and a digest — never tool text. An opt-in classifier (`--classifier-url`, `--classifier-model`) adds the reading of a model you choose, local or hosted, for what no rule names. See the [scan guide](docs/scan.md). How it compares with two other scanners, on the same servers: [scanner comparison](docs/scanner-comparison.md).
157
174
 
158
- **For a server's publisher.** If your server lists different tools where something HISTOR's sandbox lacks is installed — a launcher's runner, one per operating system — `npx -y @aimarket/warden@0.22.4 declare --out mcp-tool-sets.json -- <your server>` writes those sets to a file you publish on your own domain, and the people who get them see the publisher's declaration instead of an unseen tool set. See [declare your server's tool sets](docs/scan.md#for-publishers-declare-your-servers-tool-sets).
175
+ **For a server's publisher.** If your server lists different tools where something HISTOR's sandbox lacks is installed — a launcher's runner, one per operating system — `npx -y @aimarket/warden@0.24.0 declare --out mcp-tool-sets.json -- <your server>` writes those sets to a file you publish on your own domain, and the people who get them see the publisher's declaration instead of an unseen tool set. See [declare your server's tool sets](docs/scan.md#for-publishers-declare-your-servers-tool-sets).
159
176
 
160
177
  ## What WARDEN does not do
161
178
 
@@ -352,6 +369,7 @@ check them: [ERC-8004 identities](https://github.com/alexar76/aicom/blob/main/do
352
369
  | [Field survey: 1 108 public MCP servers](docs/mcp-survey.md) | What WARDEN decided on real third-party tool definitions — 50 servers blocked, 4 substantiated, and the six ways the rest were wrong |
353
370
  | [Scanner comparison](docs/scanner-comparison.md) | WARDEN, mcp-audit, mcp-shield, truecopy and mcpsentry on the same servers, on 14,933 npm and PyPI packages and on the MCPTox benchmark, with every judgment, the manifest and the harness |
354
371
  | [Flow guard](docs/flow-guard.md) | The Claude Code plugin's runtime guard: outside text, private data, outbound calls; the AgentDojo measurement and its limits |
372
+ | [Flow guard for Codex](docs/codex.md) | Codex hooks: no `ask`, fail-closed, managed hooks, Multica schemes |
355
373
  | [Fresh model comparison](docs/flow-guard-model-comparison-2026-10-25.md) | 720 answers; known-case improvement, uncertainty, warning custody and no observed Stop choice correction |
356
374
  | [Glama / Docker](docs/GLAMA.md) | stdio MCP server, health check, admin Build steps / CMD |
357
375
  | [MCP registries](docs/REGISTRIES.md) | Official Registry, mcp.so / Pulse |
@@ -376,7 +394,7 @@ check them: [ERC-8004 identities](https://github.com/alexar76/aicom/blob/main/do
376
394
  ## Development
377
395
 
378
396
  ```bash
379
- npm install && npm run build && npm test # 1400 tests
397
+ npm install && npm run build && npm test # 1517 tests
380
398
  ```
381
399
 
382
400
  `test/packaging.test.ts` is what keeps the headline honest: it fails if an npm runtime dependency