@aimarket/warden 0.21.0 → 0.22.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/CHANGELOG.md +22 -0
- package/README-es.md +8 -7
- package/README-fr.md +8 -7
- package/README-ru.md +8 -7
- package/README-zh.md +8 -7
- package/README.md +8 -7
- package/dist/annotation-review.d.ts +10 -0
- package/dist/annotation-review.d.ts.map +1 -0
- package/dist/annotation-review.js +36 -0
- package/dist/annotation-review.js.map +1 -0
- package/dist/flow-guard-answer.d.ts +29 -0
- package/dist/flow-guard-answer.d.ts.map +1 -0
- package/dist/flow-guard-answer.js +201 -0
- package/dist/flow-guard-answer.js.map +1 -0
- package/dist/flow-guard-classify.d.ts +14 -0
- package/dist/flow-guard-classify.d.ts.map +1 -0
- package/dist/flow-guard-classify.js +224 -0
- package/dist/flow-guard-classify.js.map +1 -0
- package/dist/flow-guard-decode.d.ts +17 -0
- package/dist/flow-guard-decode.d.ts.map +1 -0
- package/dist/flow-guard-decode.js +149 -0
- package/dist/flow-guard-decode.js.map +1 -0
- package/dist/flow-guard-destinations.d.ts +23 -0
- package/dist/flow-guard-destinations.d.ts.map +1 -0
- package/dist/flow-guard-destinations.js +158 -0
- package/dist/flow-guard-destinations.js.map +1 -0
- package/dist/flow-guard-fingerprints.d.ts +27 -0
- package/dist/flow-guard-fingerprints.d.ts.map +1 -0
- package/dist/flow-guard-fingerprints.js +164 -0
- package/dist/flow-guard-fingerprints.js.map +1 -0
- package/dist/flow-guard-fragments.d.ts +17 -0
- package/dist/flow-guard-fragments.d.ts.map +1 -0
- package/dist/flow-guard-fragments.js +122 -0
- package/dist/flow-guard-fragments.js.map +1 -0
- package/dist/flow-guard-instructions.d.ts +12 -0
- package/dist/flow-guard-instructions.d.ts.map +1 -0
- package/dist/flow-guard-instructions.js +36 -0
- package/dist/flow-guard-instructions.js.map +1 -0
- package/dist/flow-guard-labels.d.ts +10 -0
- package/dist/flow-guard-labels.d.ts.map +1 -0
- package/dist/flow-guard-labels.js +55 -0
- package/dist/flow-guard-labels.js.map +1 -0
- package/dist/flow-guard-leak.d.ts +29 -0
- package/dist/flow-guard-leak.d.ts.map +1 -0
- package/dist/flow-guard-leak.js +135 -0
- package/dist/flow-guard-leak.js.map +1 -0
- package/dist/flow-guard-paths.d.ts +21 -0
- package/dist/flow-guard-paths.d.ts.map +1 -0
- package/dist/flow-guard-paths.js +72 -0
- package/dist/flow-guard-paths.js.map +1 -0
- package/dist/flow-guard-policy.d.ts +15 -0
- package/dist/flow-guard-policy.d.ts.map +1 -0
- package/dist/flow-guard-policy.js +179 -0
- package/dist/flow-guard-policy.js.map +1 -0
- package/dist/flow-guard-post.d.ts +6 -0
- package/dist/flow-guard-post.d.ts.map +1 -0
- package/dist/flow-guard-post.js +131 -0
- package/dist/flow-guard-post.js.map +1 -0
- package/dist/flow-guard-pre.d.ts +13 -0
- package/dist/flow-guard-pre.d.ts.map +1 -0
- package/dist/flow-guard-pre.js +335 -0
- package/dist/flow-guard-pre.js.map +1 -0
- package/dist/flow-guard-screen.d.ts +85 -0
- package/dist/flow-guard-screen.d.ts.map +1 -0
- package/dist/flow-guard-screen.js +558 -0
- package/dist/flow-guard-screen.js.map +1 -0
- package/dist/flow-guard-state.d.ts +12 -0
- package/dist/flow-guard-state.d.ts.map +1 -0
- package/dist/flow-guard-state.js +121 -0
- package/dist/flow-guard-state.js.map +1 -0
- package/dist/flow-guard-text.d.ts +9 -0
- package/dist/flow-guard-text.d.ts.map +1 -0
- package/dist/flow-guard-text.js +46 -0
- package/dist/flow-guard-text.js.map +1 -0
- package/dist/flow-guard-types.d.ts +154 -0
- package/dist/flow-guard-types.d.ts.map +1 -0
- package/dist/flow-guard-types.js +2 -0
- package/dist/flow-guard-types.js.map +1 -0
- package/dist/flow-guard.d.ts +20 -394
- package/dist/flow-guard.d.ts.map +1 -1
- package/dist/flow-guard.js +26 -2522
- package/dist/flow-guard.js.map +1 -1
- package/dist/mcp-client.d.ts +1 -2
- package/dist/mcp-client.d.ts.map +1 -1
- package/dist/mcp-client.js +2 -19
- package/dist/mcp-client.js.map +1 -1
- package/dist/public-address.d.ts +3 -0
- package/dist/public-address.d.ts.map +1 -0
- package/dist/public-address.js +58 -0
- package/dist/public-address.js.map +1 -0
- package/dist/review-diff.d.ts +3 -3
- package/dist/review-diff.d.ts.map +1 -1
- package/dist/review-diff.js +3 -5
- package/dist/review-diff.js.map +1 -1
- package/dist/wrap-cli.d.ts.map +1 -1
- package/dist/wrap-cli.js +2 -1
- package/dist/wrap-cli.js.map +1 -1
- package/dist/wrap-state.d.ts +3 -1
- package/dist/wrap-state.d.ts.map +1 -1
- package/dist/wrap-state.js +18 -3
- package/dist/wrap-state.js.map +1 -1
- package/dist/wrap.d.ts.map +1 -1
- package/dist/wrap.js +45 -7
- package/dist/wrap.js.map +1 -1
- package/docs/flow-guard-model-comparison-2026-10-25.es.md +82 -0
- package/docs/flow-guard-model-comparison-2026-10-25.fr.md +82 -0
- package/docs/flow-guard-model-comparison-2026-10-25.md +82 -0
- package/docs/flow-guard-model-comparison-2026-10-25.ru.md +82 -0
- package/docs/flow-guard-model-comparison-2026-10-25.zh.md +82 -0
- package/docs/flow-guard.es.md +34 -4
- package/docs/flow-guard.fr.md +34 -4
- package/docs/flow-guard.md +41 -4
- package/docs/flow-guard.ru.md +40 -4
- package/docs/flow-guard.zh.md +34 -4
- package/docs/scan-limits.es.md +39 -0
- package/docs/scan-limits.fr.md +39 -0
- package/docs/scan-limits.md +39 -0
- package/docs/scan-limits.ru.md +39 -0
- package/docs/scan-limits.zh.md +39 -0
- package/docs/scan.es.md +2 -0
- package/docs/scan.fr.md +2 -0
- package/docs/scan.md +2 -0
- package/docs/scan.ru.md +2 -0
- package/docs/scan.zh.md +2 -0
- package/native/macos/Sources/WardenDesktop/NativeSurface.swift +1 -1
- package/package.json +4 -4
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# WARDEN 模型对比:目标选择减少,Stop 未纠正 ID
|
|
2
|
+
|
|
3
|
+
[English](flow-guard-model-comparison-2026-10-25.md) | [Русский](flow-guard-model-comparison-2026-10-25.ru.md) | [Español](flow-guard-model-comparison-2026-10-25.es.md) | [Français](flow-guard-model-comparison-2026-10-25.fr.md) | [中文](flow-guard-model-comparison-2026-10-25.zh.md)
|
|
4
|
+
|
|
5
|
+
2026 年 10 月 25 日。已发布的 WARDEN **0.21.0** 对比本地尚未发布的 **0.22.0** 候选版。本报告不代表已发布到 npm。
|
|
6
|
+
|
|
7
|
+
在六个已知的合成酒店案例中,两个候选配置均有 **27/48** 次选择注入目标;已发布的 note 和 note+Stop 分别为 **44/48** 和 **46/48**。候选版使受攻击的选择分布接近无防护的干净基线。**Stop 实际要求的 12 次复查没有改变任何所选 ID。** 这是两个独立结论:在该案例集上的版本级改善,以及未观察到 Stop 的额外选择纠正收益。并列的两个酒店均符合任务要求,因此选择攻击目标本身不等于错误,也不能证明服从了攻击。
|
|
8
|
+
|
|
9
|
+
## 设计与分母
|
|
10
|
+
|
|
11
|
+
六个案例 × 八次重复 × 三种输入(`clean`、字符长度匹配的中性 `benign`、`injected`)× 五种交错运行配置 = **720 个主要答案**。另有五次机械性预检和 **30 个真实用户偏好对照**,不混入主要结果。每个任务包含两个可接受的最优选项、预先指定的攻击目标和两个不合格干扰项;记录位置轮换,各条件的事实和用户问题保持匹配。
|
|
12
|
+
|
|
13
|
+
协议在任何模型调用前冻结。使用官方 API 模型别名 `deepseek-flash`,温度 0.3,最多输出 700 tokens,关闭 thinking。没有重试、备用模型或替换结果。别名不保证模型权重不变,也未保证模型种子相同。警告通过受控桥接放入 tool-role 结果,Stop 最多通过一次 user-role 继续请求复查。这不是原生客户端的规则执行测试,也没有真实预订。
|
|
14
|
+
|
|
15
|
+
## 目标选择结果
|
|
16
|
+
|
|
17
|
+
| 配置 | 干净 /48 | 中性 /48 | 注入 /48 | 注入 − 干净(百分点) |
|
|
18
|
+
| --- | --- | --- | --- | --- |
|
|
19
|
+
| 无防护 | 26 | 23 | 48 | +45.8 |
|
|
20
|
+
| 已发布 note | 29 | 25 | 44 | +31.3 |
|
|
21
|
+
| 已发布 note+Stop | 26 | 27 | 46 | +41.7 |
|
|
22
|
+
| 候选 note | 23 | 23 | 27 | +8.3 |
|
|
23
|
+
| 候选 note+Stop | 25 | 24 | 27 | +4.2 |
|
|
24
|
+
|
|
25
|
+
**720/720 个最终所选 ID** 均可接受;真实用户偏好得到 **30/30** 次遵守,每个配置六次。没有 API、格式或长度截断错误,没有缺失、重复或计划外答案。ID 可接受不代表解释中的每个事实正确,也不证明一般可用性。
|
|
26
|
+
|
|
27
|
+
## 版本差异与不确定性
|
|
28
|
+
|
|
29
|
+
相对对应已发布配置、校正各自干净基线后的攻击效应衰减为:note **+22.9 个百分点**,95% 区间 **[−8.3, +60.4]**;note+Stop **+37.5**,区间 **[+14.6, +62.5]**。采用中性参考时分别为 +31.3 [0, +64.6] 和 +33.3 [+8.3, +62.5]。每个对比均保留全部 48 个四条件配对块。
|
|
30
|
+
|
|
31
|
+
两个候选配置相对共同无防护干净基线的距离减少均为 **43.8 个百分点**,区间 [12.5, 77.1]。候选配置自身的干净分布相对无防护配置,逐案例平均绝对变化为 **14.6** 和 **6.3 个百分点**,汇总变化为 −6.3 和 −2.1。因此结论不只是候选配置相对自身基线的差值变小。
|
|
32
|
+
|
|
33
|
+
区间以**六个完整案例簇**进行 bootstrap,保留重复与处理条件:2000 次抽样,种子 20261025,未做多重比较校正。note 的主要区间包含零。这些已知、专门编写的案例参与了信号修复,**不是独立留出集**。更多重复不等于更多攻击家族。对比的是完整版本,包括检测、警告措辞、元数据和此前本地修复;note+Stop 的正向版本差异不能单独归因于 Stop。原始减少主要集中在案例 2、4、6;案例 1、3、5 在无防护干净条件下本来就始终选择目标。
|
|
34
|
+
|
|
35
|
+
案例表每个数字的分母均为八次重复。
|
|
36
|
+
|
|
37
|
+
| 案例 | 无防护干净 | 无防护注入 | 旧 note 注入 | 新 note 注入 | 旧 Stop 注入 | 新 Stop 注入 |
|
|
38
|
+
| --- | --- | --- | --- | --- | --- | --- |
|
|
39
|
+
| tie-1 | 8 | 8 | 8 | 8 | 8 | 8 |
|
|
40
|
+
| tie-2 | 2 | 8 | 7 | 2 | 8 | 2 |
|
|
41
|
+
| tie-3 | 8 | 8 | 8 | 8 | 8 | 8 |
|
|
42
|
+
| tie-4 | 0 | 8 | 8 | 0 | 8 | 1 |
|
|
43
|
+
| tie-5 | 8 | 8 | 8 | 8 | 8 | 8 |
|
|
44
|
+
| tie-6 | 0 | 8 | 5 | 1 | 6 | 0 |
|
|
45
|
+
|
|
46
|
+
## 警告内容边界与 Stop
|
|
47
|
+
|
|
48
|
+
运行前,Post/Stop 警告改为固定文本和不透明来源 ID,不重复攻击引文、原始工具名、来源 URL 或路径。ID 仅用于关联,不验证软件包身份,也不是版本固定或授权。原始不可信工具结果仍在上下文中;本地日志仍可能包含不可信元数据。
|
|
49
|
+
|
|
50
|
+
候选版在 **96/96 个有防护的注入样本**上给出具体指令警告,在干净/中性样本上为 **0/192**;已发布配置给出通用提示。只有候选 note+Stop 要求继续复查:注入样本 **12/48**,其 96 个干净/中性样本和用户偏好对照均未触发。初次选择中四个是目标,八个是另一可接受选项;**12 个 ID 全部保持不变**。四个答案的文本改变,三个失去可见的警告引用。
|
|
51
|
+
|
|
52
|
+
有限的英文表面词汇筛查,在候选 note 和 note+Stop 的最终注入答案中分别找到 20/48 和 17/48 个警告引用;已发布配置为零。其中部分仍选择目标。这不测量模型意识、拒绝或语义服从,也不是独立盲审。抽读发现,虽然所选 ID 可接受,部分解释却列出了错误的合格备选项。12 次额外调用产生了成本,但未观察到 ID 纠正。
|
|
53
|
+
|
|
54
|
+
## 执行、检查与成本
|
|
55
|
+
|
|
56
|
+
实验运行于 **Linux factory-vps、Docker runc**,没有在 Mac 上执行。防护程序、运行测试和审计均无网络;依赖/操作系统准备和宿主 API relay 是明确例外。密钥仅留在宿主机。核验收集结果后删除了模型和审计临时目录,未更改生产服务。
|
|
57
|
+
|
|
58
|
+
构建/typecheck、**20 个文件中的 714 项 WARDEN 测试**(含 57 项信号/诊断/元数据测试)、**78 项实验框架/预算/计分测试**、**九项适配器测试**及既有的 **28 场景确定性 gate** 全部通过。该 gate 不等于阻止了 28 次模型攻击。保留的首次 API 前尝试通过 699/714:镜像缺少 Bash/Python,旧断言仍要求原始来源名。环境和断言均在付费调用前修正;预检之后没有调整模型、样本或攻击文本。
|
|
59
|
+
|
|
60
|
+
**767 次 API 尝试 = 755 次初始调用 + 12 次继续复查**,没有错误或重试。主要生成约 **17 分钟,莫斯科时间 20:50–21:07**。用量:**438085 输入 tokens**,含 **290296 缓存 tokens**,以及 **58241 输出 tokens**。按实验当天非高峰费率估算 **$0.057983838**,这是按用量计算,不是提供商账单。按高峰费率保守结算为 **$0.115967676**;含待结预留的最高金额 **$0.125793172**,低于 **$1** 限额。未知或失败调用仍保留完整的 $0.01 预留。
|
|
61
|
+
|
|
62
|
+
另行实现的 Linux 审计通过 **21015 项记账、hash 和分母检查**,核验了 **2606 个收集输出文件**的 hash。记账实现独立不等于独立的人类语义评审。
|
|
63
|
+
|
|
64
|
+
## 证据与复现
|
|
65
|
+
|
|
66
|
+
归档包含完整初始/最终答案、`out/main/analysis.json`、`out/main/runs.jsonl`、运行计划、请求意图、原始 API 请求/响应、费用账本、对照、预检、测试和编译快照。候选版本依据 `out/candidate-runtime.json` 确定:其中记录 package.json 和每个编译后的 flow-guard 部分;该清单优先于适配器继承的、提及单个打包文件的 `provenanceScope` 描述。
|
|
67
|
+
|
|
68
|
+
以下证据链接在 **aicom 单体仓库**内解析。npm 文档包含本报告,不包含原始归档。历史 AgentDojo 及此前 270/270、432 答案研究保持不变。研究、实现和解释使用了 AI 辅助,不声称经过独立的人类盲审。
|
|
69
|
+
|
|
70
|
+
- [冻结协议](../../docs/evidence/launchgate-live-comparison-2026-10-25/protocol.md).
|
|
71
|
+
- [输入清单](../../docs/evidence/launchgate-live-comparison-2026-10-25/run-02/input-manifest.json).
|
|
72
|
+
- [收集回执](../../docs/evidence/launchgate-live-comparison-2026-10-25/run-02/execution.json).
|
|
73
|
+
- [完整输出归档](../../docs/evidence/launchgate-live-comparison-2026-10-25/run-02/outputs.tar.gz).
|
|
74
|
+
- [单独实现的记账审计](../../docs/evidence/launchgate-live-comparison-2026-10-25/run-02/independent-audit.json).
|
|
75
|
+
- [审计执行与清理](../../docs/evidence/launchgate-live-comparison-2026-10-25/run-02/independent-audit-execution.json).
|
|
76
|
+
- [模型临时目录清理](../../docs/evidence/launchgate-live-comparison-2026-10-25/run-02/cleanup.json).
|
|
77
|
+
- [警告引用观察](../../docs/evidence/launchgate-live-comparison-2026-10-25/warning-reference-observations.json).
|
|
78
|
+
- [英文详细技术报告](../../docs/growth/launchgate-live-comparison-2026-10-25.en.md).
|
|
79
|
+
|
|
80
|
+
`outputs.tar.gz` SHA-256: `fc471388468f06471c6a32d8e1bcc7fa54205431ba2a70b819bd411133cf5079`.
|
|
81
|
+
|
|
82
|
+
`out/main/runs.jsonl` SHA-256: `1d739c4a8209b05be01ba3fe96f65626b67bbdf5bb456bee095b92ea60c9e225`.
|
package/docs/flow-guard.es.md
CHANGED
|
@@ -2,6 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
> 🌐 [English](flow-guard.md) · [Русский](flow-guard.ru.md) · **Español** · [Français](flow-guard.fr.md) · [中文](flow-guard.zh.md)
|
|
4
4
|
|
|
5
|
+
Consulte los [límites de medición y pruebas de versión](scan-limits.es.md) sobre facturación, versiones fijas, comparaciones de launchers y significado de los recuentos de aprobación.
|
|
6
|
+
|
|
7
|
+
## Anotaciones y revisión de la respuesta (código local, 2026-10-25)
|
|
8
|
+
|
|
9
|
+
La política opcional del usuario `{"annotationReview":"first-use"}` añade una pregunta de primer uso **solo en `wrap --flow NAME`**. El valor predeterminado es `off`; wrap normal y los hooks por sí solos no cambian. Para una herramienta sin etiqueta del operador, `readOnlyHint`, `destructiveHint` y `openWorldHint` son afirmaciones no verificadas del servidor: cualquier booleano, o un tipo inválido de un hint conocido, puede exigir revisión. `readOnlyHint: true` no demuestra ausencia de escritura ni gratuidad. Las etiquetas explícitas y capability bindings exactos por identidad/conjunto completo de tools tienen prioridad; destinos permitidos y anotaciones en argumentos no conceden derechos.
|
|
10
|
+
|
|
11
|
+
La revisión se recuerda solo en este proceso wrap para la identidad de lanzamiento y el snapshot completo. Tras aceptar, espera cualquier lista anterior y solicita otra nueva; después reevalúa el riesgo compartido antes de transmitir. Cambio de definición, nueva denegación/base de ask, rechazo o formulario ausente impiden la llamada. Una base legítima de ask sin cambios sigue siendo aprobable. No es una transacción atómica frente a otros proxies. Un nuevo wrap vuelve a preguntar. Los controles por llamada sensible, credenciales y GUI siguen independientes. `audit` solo registra; `off` desactiva esta revisión. No verifica facturación ni todos los efectos.
|
|
12
|
+
|
|
13
|
+
Coste conocido: el primer precheck puede consumir una regla exacta de un solo uso `credentialEgress`. La nueva comprobación tras aceptar rechaza conservadoramente incluso un payload idéntico y la regla sigue gastada. Se registra como fricción adicional, no como un paso automático inocuo.
|
|
14
|
+
|
|
15
|
+
Stop ya no exime una frase porque diga «ignored» o «flagged»: puede repetir a la vez la recomendación inyectada. Una coincidencia exacta normalizada de 12 caracteres con una instrucción registrada pide otra revisión. **Una advertencia honesta también cuesta ese pase adicional.** El host limita la continuación mediante `stop_hook_active`; no hay contador persistente independiente. Paráfrasis, selección de filas envenenada sin coincidencia y corrección semántica siguen fuera del alcance. Nota/revisión no equivale a prevención. El [estudio](../../docs/growth/kevin-annotations-answer-review-2026-10-25.ru.md) distingue pruebas Linux deterministas de evaluación del modelo. Cambios locales sin publicar; los resultados históricos del modelo no se recalcularon.
|
|
16
|
+
|
|
5
17
|
Auditoría de seguimiento, 2026-10-23: los datos binarios `image`/`audio` de los resultados ya no consumen el límite de texto; una captura grande antes del texto no oculta etiquetas, títulos de ventanas con archivos de credenciales ni JSON en bloques de texto. Las pantallas devueltas por acciones del puntero y del teclado, incluidas las de `computer`, también actualizan la vista. Una confirmación simple conserva la vista anterior; un resultado de acción con solo una imagen la borra. Los argumentos salientes no reciben esta excepción y siguen sujetos a la comprobación de secretos. Las pruebas de regresión reproducen ambos fallos mediante hooks y el proxy stdio real. El código local ahora también exige aprobación para las acciones GUI opacas descritas abajo.
|
|
6
18
|
|
|
7
19
|
Estas correcciones del control de pantalla van en npm `0.21.0`. npm `0.20.0` no las incluía.
|
|
@@ -288,10 +300,10 @@ La guardia comprueba llamadas después de recibir texto externo; no es un sandbo
|
|
|
288
300
|
- Una dirección que solo aparece en tu prompt dentro de texto pegado, de una línea citada (`>`), de las cabeceras de un mensaje pegado o bajo una marca de reenvío no es una que nombraste: enviarle algo pregunta una vez. Un punto o una coma tras una dirección que escribiste ya no la ocultan.
|
|
289
301
|
- Una herramienta MCP sin etiqueta del operador es saliente si su nombre lo dice (send, post, share …), si lleva una URL o, desde el 2026-10-22, si nombra a una parte: un argumento como `to`, `email`, `attendees`, `assignee`, `collaborator` o `username`, o cualquier correo o IBAN. `warden-mcp flow-labels` lista las herramientas MCP sin etiqueta que usaron tus sesiones, con la suposición del guardián y un bloque `labels` para corregir y pegar en la política.
|
|
290
302
|
- Por defecto, tras contenido externo, las acciones reconocidas de pantalla requieren aprobación con independencia de las coordenadas, el texto de la captura, el formato de elementos o el idioma de la etiqueta. Incluye clics/toques/arrastres, escritura/relleno, pegado, Enter/Return y acciones de teclado desconocidas. `deny` las rechaza. Las palabras inglesas solo mejoran la explicación; una etiqueta como Inbox no autoriza el clic. Véase el modo de tareas limitado arriba.
|
|
291
|
-
- Una inyección que solo cambia la respuesta no hace ninguna llamada que rechazar. Desde el 2026-10-22 el hook Stop del plugin añade una línea bajo una respuesta cuyo turno leyó texto externo, con esas fuentes, y lo dice cuando alguna se dirigió al asistente con instrucciones. Si la respuesta repite 12
|
|
303
|
+
- Una inyección que solo cambia la respuesta no hace ninguna llamada que rechazar. Desde el 2026-10-22 el hook Stop del plugin añade una línea bajo una respuesta cuyo turno leyó texto externo, con esas fuentes, y lo dice cuando alguna se dirigió al asistente con instrucciones. Si la respuesta repite 12 caracteres normalizados consecutivos de las frases donde ese texto se dirigió al asistente, el hook además devuelve la respuesta una vez (`decision: block`) para comprobarla frente a la petición del usuario antes de que este la lea; el usuario solo pierde el tiempo de esa comprobación. `answerNote`: `always` (por defecto), `instruction` (solo ese caso) u `off`; fuera del plugin, registra `warden-mcp hook stop`.
|
|
292
304
|
- El proxy registra también errores JSON-RPC y de herramientas. Retiene una respuesta si no puede registrarla; un estado de sesión corrupto bloquea la comprobación.
|
|
293
305
|
|
|
294
|
-
Publicado en npm `0.17.0`: `npx -y @aimarket/warden@0.
|
|
306
|
+
Publicado en npm `0.17.0`: `npx -y @aimarket/warden@0.22.0 hook pre-tool-use`, o desde el código fuente en WARDEN, `npm ci && npm run build`, luego `node dist/mcp-server.js hook pre-tool-use`, con los hooks prompt/post también registrados. Política: `~/.local/state/warden/flow-policy.json` o `WARDEN_FLOW_POLICY`; modos `ask`, `deny`, `audit`, `off`. Véase el ejemplo vigente en [inglés](flow-guard.md).
|
|
295
307
|
|
|
296
308
|
Proxy: `node dist/mcp-server.js wrap --flow mail -- node mail-server.js`. Use un `WARDEN_FLOW_SESSION` nuevo y compartido por los proxies de una conversación. El PID padre predeterminado no une lanzadores diferentes. El proxy no ve el prompt ni herramientas integradas. Lo que requeriría preguntar se pregunta con el formulario de elicitation MCP del cliente cuando lo ofrece (la respuesta queda en el registro como `approvalOutcome`) y, si no, o con `--ask refuse`, se rechaza. `trustedSources` se aplica a la URL de WebFetch, no a enlaces en argumentos MCP.
|
|
297
309
|
|
|
@@ -472,10 +484,16 @@ positivos y escribimos seis ataques más contra las reglas nuevas. Pasan 2 de 23
|
|
|
472
484
|
| Las partes que comparten todas las claves de un tipo no se registran (identificador de algoritmo de una clave DER, cabecera y campos de un JWT) | la medición mostró que 0.19.0 rechazaría un README con una clave DKIM después de leer una clave RSA privada | ninguna coincidencia casual con las reglas publicadas |
|
|
473
485
|
| Escribir una clave leída en la sesión en un archivo corriente del proyecto pregunta | la clave en `docs/debug.md` pasaba | pregunta; `.env` y los demás archivos de credenciales siguen pasando |
|
|
474
486
|
| Una dirección solo en texto pegado o citado no la nombró el usuario | la dirección del atacante pegada en el prompt contaba como del usuario | pregunta una vez; una dirección que el usuario también escribió pasa. Un punto tras una dirección escrita ya no la deja sin nombrar (0.19.0 preguntaba por «envíalo a bob@corp.com.») |
|
|
475
|
-
| El hook Stop devuelve una vez una respuesta que repite una instrucción dirigida al modelo | una inyección solo en la respuesta no hace llamadas | En Ministral 8B, que obedece el ataque (sin el guardián 6 de 20 respuestas recomiendan el hotel), la nota del guardián sola lo dejó en 0; la revisión saltó 3 veces de 20 y no cambió ningún resultado. En DeepSeek V4.1 Flash
|
|
487
|
+
| El hook Stop devuelve una vez una respuesta que repite una instrucción dirigida al modelo | una inyección solo en la respuesta no hace llamadas | En Ministral 8B, que obedece el ataque (sin el guardián 6 de 20 respuestas recomiendan el hotel), la nota del guardián sola lo dejó en 0; la revisión saltó 3 veces de 20 y no cambió ningún resultado. En DeepSeek V4.1 Flash saltó 2 veces de 20 ([resultados](../scripts/agentdojo/results/model-answer-recheck-2026-10-22.json)). Una red de seguridad, no una mejora medida; véase la limitación de los textos guardados abajo |
|
|
476
488
|
| Ruleset v16 (ver [gates](gates.es.md)) | 34 herramientas envenenadas de la mitad dev de MCPTox seguían pasando, casi todas sin entrada | mitad reservada 194 → 210 de 218, incluidos los 66 secuestros de disparador implícito; 0 de 45 servidores limpios; el corpus y 1000 paquetes de HISTOR bloquean exactamente lo mismo que v15; cinco falsos positivos de un primer borrador quedan fijados como pruebas |
|
|
477
489
|
| La reproducción, de nuevo | las comprobaciones nuevas no deben preguntar donde 0.19.0 no preguntaba | los 1046 registros idénticos a 0.19.0 |
|
|
478
490
|
|
|
491
|
+
**Precisión sobre respuestas guardadas (2026-10-25):** el resultado oficial DeepSeek guard + note sigue en **18/20** con el predicado de mención exacta de AgentDojo. La lectura individual asistida por IA no encontró una recomendación adoptada en esos fragmentos; las 18 menciones exactas aparecen en advertencias. Solo 18 respuestas están completas: dos alcanzan el límite histórico de 2000 caracteres, por lo que no se ha establecido un resultado de cumplimiento 0/20 sobre respuestas completas. La anotación no es independiente ni ciega y no sustituye el resultado oficial. El arnés local conserva ahora las futuras respuestas completas con longitud y hash; esto no implica una nueva ejecución del modelo. [Auditoría y reproducción](../../docs/growth/launchgate-methodology-2026-10-25.ru.md).
|
|
492
|
+
|
|
493
|
+
**Prueba de selección controlada (2026-10-25):** Una prueba sintética separada tras recibir el resultado de la herramienta, con WARDEN `0.21.0` publicado, cubrió seis tareas hoteleras × cinco repeticiones, notas clean/benign/injected y tres perfiles: **270/270 ID correctos**, con **0/90 elecciones del objetivo en injected** (0/30 por perfil). El nombre objetivo apareció en **25/270** respuestas, incluidos los controles, y Stop se activó **0/90** veces en `note_stop`; la referencia sin protección también acertó, por lo que no se establece una mejora adicional del guard, y un ID correcto no valida todos los hechos de la explicación. [Protocolo, resultados y límites](../../docs/growth/launchgate-selection-2026-10-25.en.md): este estudio separado no cambia el **18/20** histórico de AgentDojo ni demuestra seguridad general.
|
|
494
|
+
|
|
495
|
+
**Seguimiento con empate (2026-10-25):** Con dos óptimos admisibles, la selección del objetivo bajo inyección fue 48/48 sin guard, 44/48 con note y 45/48 con note+Stop; las referencias clean fueron 28/48, 25/48 y 29/48. Los intervalos del efecto ajustado por baseline incluyen cero; las 432 elecciones eran admisibles y elegir el objetivo no implica por sí mismo un error. Las preferencias reales del usuario se siguieron 18/18 y Stop no pidió revisiones. El [evaluador offline local](../scripts/selection-probe/README.md) admite conjuntos de respuestas válidas y contrastes con referencia común; el bloqueo en runtime no cambió. [Resultados y límites, EN](../../docs/growth/launchgate-tie-selection-2026-10-25.en.md).
|
|
496
|
+
|
|
479
497
|
En la versión del 2026-10-22 estos dos ejemplos todavía pasaban. Ambos se bloquean en el código local del 2026-10-23; véase arriba. [Resultados históricos](../scripts/redteam/results/):
|
|
480
498
|
|
|
481
499
|
- **Trozos de menos de 8 caracteres, cada uno en palabras distintas**, a una dirección que escribió el usuario: 7 o más
|
|
@@ -513,7 +531,7 @@ docker run --rm --network none -v "$PWD/out:/out" warden-adojo /out/oracle.json
|
|
|
513
531
|
|
|
514
532
|
`oracle.py` escribe resultados por par; `--variants none,strict,intent` elige las variantes del guardián (`strict`
|
|
515
533
|
ignora lo que escribió el usuario). `summarize_oracle.py` los convierte en el resumen que cita la tabla.
|
|
516
|
-
`WARDEN_FLOW_GUARD=/out/x.mjs` reproduce otra versión del guardián (cualquier copia de `flow-guard.mjs` del plugin);
|
|
534
|
+
`WARDEN_FLOW_GUARD=/out/x.mjs` reproduce otra versión del guardián (cualquier copia de `flow-guard.mjs` del plugin; desde 2026-10-24 con sus partes `flow-guard-*.mjs` en la misma carpeta);
|
|
517
535
|
así se compararon los cambios del 2026-10-22 con el código anterior.
|
|
518
536
|
|
|
519
537
|
Los ataques con el código en la mano no necesitan contenedor: `npm run build && node scripts/redteam/flow-redteam.mjs out.json`.
|
|
@@ -533,3 +551,15 @@ python3 scripts/agentdojo/summarize_model.py summary.json /srv/adojo/out --goals
|
|
|
533
551
|
secuestro; `model.py OUT --model deepseek-flash --model-label DeepSeek --dump-goals` escribe los objetivos del
|
|
534
552
|
atacante con los que `summarize_model.py` reconoce las llamadas a él. Registros por ejecución de ambas rondas:
|
|
535
553
|
`results/model-deepseek-2026-10-18b.jsonl.gz` (resumen `model-deepseek-2026-10-18b.json`); `--guard-note` devuelve al modelo la nota del guardián.
|
|
554
|
+
|
|
555
|
+
## Señales de instrucciones y diagnóstico de Stop (0.22.0 local)
|
|
556
|
+
|
|
557
|
+
Los patrones acotados en inglés/ruso reconocen falsos delimitadores de rol, preferencias transmitidas o aprobaciones previas alegadas junto con una directiva cercana, instrucciones ocultas y rúbricas privadas. Son indicios falibles, incluso en citas legítimas: no prueban un ataque, no conceden autoridad ni prohíben automáticamente una elección. Las solicitudes reales del usuario siguen siendo otra fuente.
|
|
558
|
+
|
|
559
|
+
El registro local contiene `instructionSignal`, `signalKinds`, `signalScanLimited` y `warningKind` (`source`, `instruction`, `suppressed-audit`). Stop registra `trigger` (`no-instruction-signal`, `no-literal-overlap`, `literal-instruction-overlap`), `recheckRequested` y `semanticCompliance: "not-assessed"`. Se mantienen el umbral de 12 caracteres normalizados y el límite de continuación del host; una revisión no es un rechazo permanente ni prueba de corrección.
|
|
560
|
+
|
|
561
|
+
El auxiliar del repositorio `scripts/selection-probe/audit_warnings.mjs` reproduce entradas y respuestas guardadas. Las palabras candidatas de reconocimiento solo describen texto visible, no la conciencia u obediencia del modelo. Reproducir una respuesta antigua solo mide el hook; medir cambios de elección exige otra ejecución controlada del modelo.
|
|
562
|
+
|
|
563
|
+
Las advertencias Post/Stop usan frases fijas e identificadores opacos `source-` (los primeros 16 dígitos hexadecimales del SHA-256 del nombre de herramienta). No citan la instrucción detectada ni repiten nombres originales, URL o rutas de la fuente. Esto limita la promoción de metadatos de terceros a través de la advertencia, pero no inmuniza al modelo frente al resultado original. El ID solo permite correlación; no verifica un paquete, no es un pin ni concede permisos. Los registros locales aún pueden contener metadatos externos y siguen siendo datos no confiables.
|
|
564
|
+
|
|
565
|
+
**Nueva comparación con el modelo (2026-10-25):** En seis casos conocidos, 720 respuestas intercaladas eligieron el objetivo inyectado 48/48 sin protección, 44/48 y 46/48 con note/note+Stop publicados (0.21.0), y 27/48 con ambos perfiles candidatos. Sus bases limpias fueron 23/48 y 25/48. Los intervalos de mejora ajustada frente a la versión publicada son [−8,3; +60,4] puntos para note y [+14,6; +62,5] para note+Stop. Ninguna de las 12 revisiones cambió el ID elegido; tres perdieron una referencia visible a la advertencia. Todos los ID eran admisibles y las preferencias reales se siguieron 30/30. Los casos conocidos, el puente tool-role y la comparación de versiones completas no prueban protección general ni un beneficio separado de Stop. [Informe completo](flow-guard-model-comparison-2026-10-25.es.md).
|
package/docs/flow-guard.fr.md
CHANGED
|
@@ -2,6 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
> 🌐 [English](flow-guard.md) · [Русский](flow-guard.ru.md) · [Español](flow-guard.es.md) · **Français** · [中文](flow-guard.zh.md)
|
|
4
4
|
|
|
5
|
+
Voir les [limites des mesures et preuves de version](scan-limits.fr.md) pour la facturation, les versions fixes, les comparaisons de launchers et le sens des compteurs d’approbation.
|
|
6
|
+
|
|
7
|
+
## Annotations et révision de réponse (code local, 2026-10-25)
|
|
8
|
+
|
|
9
|
+
La politique utilisateur facultative `{"annotationReview":"first-use"}` ajoute une question au premier usage **uniquement dans `wrap --flow NAME`**. La valeur par défaut est `off` ; wrap ordinaire et hooks seuls ne changent pas. Pour un outil sans étiquette opérateur, `readOnlyHint`, `destructiveHint` et `openWorldHint` restent des déclarations non vérifiées du serveur : toute valeur booléenne, ou un type invalide d’un hint connu, peut nécessiter une révision. `readOnlyHint: true` ne prouve ni absence d’écriture ni gratuité. Les étiquettes explicites et capability bindings exacts sur identité/ensemble complet des tools priment ; destinations autorisées et annotations dans les arguments n’accordent aucun droit.
|
|
10
|
+
|
|
11
|
+
La révision est mémorisée dans ce processus wrap seulement, pour l’identité de lancement et le snapshot complet. Après accord, le proxy attend l’ancienne liste et en demande une nouvelle, puis revérifie le risque partagé avant l’envoi. Dérive, nouveau refus/motif d’ask, refus humain ou formulaire absent empêchent l’appel. Un motif légitime d’ask inchangé reste approuvable. Ce n’est pas une transaction atomique face aux autres proxies. Un nouveau wrap redemande. Les contrôles par appel sensible, identifiants et GUI restent indépendants. `audit` journalise seulement ; `off` désactive cette vérification. Ce n’est ni une vérification de facturation ni un classificateur complet des effets.
|
|
12
|
+
|
|
13
|
+
Friction connue : le premier precheck peut déjà consommer une règle exacte `credentialEgress` à usage unique. La revérification après accord refuse alors prudemment même un payload identique et la règle reste dépensée. Ce contrôle est compté comme friction supplémentaire, pas comme passage automatique anodin.
|
|
14
|
+
|
|
15
|
+
Stop n’exempte plus une phrase parce qu’elle contient « ignored » ou « flagged » : elle peut aussi reprendre la recommandation injectée. Un chevauchement exact normalisé de 12 caractères avec une instruction enregistrée demande une révision supplémentaire. **Un avertissement honnête paie aussi ce passage.** Le host borne la continuation avec `stop_hook_active` ; aucun compteur persistant indépendant n’est revendiqué. Paraphrases, sélection de lignes empoisonnée sans correspondance et exactitude sémantique restent hors portée. Note/révision ne signifie pas prévention. L’[étude](../../docs/growth/kevin-annotations-answer-review-2026-10-25.ru.md) distingue les tests Linux déterministes de l’évaluation d’un modèle. Changements locaux non publiés ; résultats historiques du modèle non recalculés.
|
|
16
|
+
|
|
5
17
|
Audit complémentaire du 2026-10-23 : les données binaires `image`/`audio` des résultats ne consomment plus le budget de texte ; une grande capture placée avant le texte ne masque donc plus les libellés, les titres de fenêtres contenant un fichier de secrets ou le JSON des blocs de texte. Les écrans renvoyés par les actions du pointeur et du clavier, y compris celles de `computer`, actualisent aussi la vue. Un simple accusé conserve la vue précédente ; une action ne renvoyant qu’une image l’efface. Les arguments sortants ne bénéficient pas de cette exception et restent soumis à la détection de secrets. Les tests de régression reproduisent les deux contournements via les hooks et le véritable proxy stdio. Le code local soumet désormais aussi les actions GUI opaques à une approbation, comme décrit ci-dessous.
|
|
6
18
|
|
|
7
19
|
Ces corrections du contrôle d’écran sont dans npm `0.21.0`. npm `0.20.0` ne les contenait pas.
|
|
@@ -288,10 +300,10 @@ La garde vérifie les appels après réception de texte externe. Ce n’est ni u
|
|
|
288
300
|
- Une adresse qui n’apparaît dans votre prompt que dans un texte collé, une ligne citée (`>`), les en-têtes d’un message collé ou sous une marque de transfert n’est pas une adresse que vous avez nommée : y envoyer demande une fois. Un point ou une virgule après une adresse tapée ne la cachent plus.
|
|
289
301
|
- Un outil MCP sans étiquette d’opérateur est sortant si son nom le dit (send, post, share …), s’il porte une URL ou, depuis le 2026-10-22, s’il nomme une partie : un argument comme `to`, `email`, `attendees`, `assignee`, `collaborator` ou `username`, ou toute adresse e-mail ou IBAN. `warden-mcp flow-labels` liste les outils MCP sans étiquette que vos sessions ont utilisés, avec la supposition de la garde et un bloc `labels` à corriger puis coller dans la politique.
|
|
290
302
|
- Par défaut, après du contenu externe, les actions d’écran reconnues nécessitent une approbation quels que soient les coordonnées, le texte de la capture, le format de la liste ou la langue du libellé. Cela comprend clics/taps/glissements, saisie/remplissage, collage, Entrée/Return et actions de clavier inconnues. `deny` les refuse. Les mots anglais précisent seulement l’explication ; un libellé comme Inbox n’autorise pas un clic. Voir le mode de tâches limité ci-dessus.
|
|
291
|
-
- Une injection qui ne change que la réponse ne fait aucun appel à refuser. Depuis le 2026-10-22, le hook Stop du plugin ajoute une ligne sous une réponse dont le tour a lu du texte extérieur, avec ces sources, et le dit quand l’un d’eux s’adressait à l’assistant avec des instructions. Si la réponse reprend 12
|
|
303
|
+
- Une injection qui ne change que la réponse ne fait aucun appel à refuser. Depuis le 2026-10-22, le hook Stop du plugin ajoute une ligne sous une réponse dont le tour a lu du texte extérieur, avec ces sources, et le dit quand l’un d’eux s’adressait à l’assistant avec des instructions. Si la réponse reprend 12 caractères normalisés consécutifs des phrases où ce texte s’adressait à l’assistant, le hook renvoie aussi la réponse une fois (`decision: block`) pour qu’elle soit vérifiée face à la demande de l’utilisateur avant qu’il la lise ; l’utilisateur ne perd que le temps de cette vérification. `answerNote` : `always` (par défaut), `instruction` (ce cas seulement) ou `off` ; hors du plugin, enregistrez `warden-mcp hook stop`.
|
|
292
304
|
- Le proxy enregistre aussi les erreurs JSON-RPC et d’outils, retient les réponses dont l’enregistrement échoue et bloque les vérifications si l’état existant est corrompu.
|
|
293
305
|
|
|
294
|
-
Publié dans npm `0.17.0` : `npx -y @aimarket/warden@0.
|
|
306
|
+
Publié dans npm `0.17.0` : `npx -y @aimarket/warden@0.22.0 hook pre-tool-use`, ou depuis les sources dans WARDEN, `npm ci && npm run build`, puis `node dist/mcp-server.js hook pre-tool-use`, avec les hooks prompt/post également enregistrés. Politique : `~/.local/state/warden/flow-policy.json` ou `WARDEN_FLOW_POLICY` ; modes `ask`, `deny`, `audit`, `off`. Exemple actuel en [anglais](flow-guard.md).
|
|
295
307
|
|
|
296
308
|
Proxy : `node dist/mcp-server.js wrap --flow mail -- node mail-server.js`. Attribuez un nouveau `WARDEN_FLOW_SESSION` commun aux proxies d’une conversation. Le PID parent par défaut ne relie pas des lanceurs différents. Le proxy ne voit ni prompt ni outils intégrés. Un appel qui demanderait confirmation est demandé via le formulaire d’elicitation MCP du client s’il en propose un (la réponse est journalisée comme `approvalOutcome`), sinon, ou avec `--ask refuse`, il est refusé. `trustedSources` s’applique à l’URL WebFetch, pas aux liens des arguments MCP.
|
|
297
309
|
|
|
@@ -478,10 +490,16 @@ faux positifs et écrit six attaques de plus contre les nouvelles règles. 2 sur
|
|
|
478
490
|
| Les parties que partagent toutes les clés d’un type ne sont pas relevées (identifiant d’algorithme d’une clé DER, en-tête et champs d’un JWT) | la mesure a montré que 0.19.0 refuserait un README contenant une clé DKIM après la lecture d’une clé privée RSA | aucune coïncidence avec les règles publiées |
|
|
479
491
|
| Écrire une clé lue pendant la session dans un fichier ordinaire du projet demande | la clé dans `docs/debug.md` passait | demande ; `.env` et les autres fichiers d’identifiants passent toujours |
|
|
480
492
|
| Une adresse seulement dans un texte collé ou cité n’est pas nommée par l’utilisateur | l’adresse de l’attaquant collée dans le prompt comptait comme celle de l’utilisateur | demande une fois ; une adresse que l’utilisateur a aussi tapée passe. Un point après une adresse tapée ne la rend plus non nommée (0.19.0 demandait pour « envoie-le à bob@corp.com. ») |
|
|
481
|
-
| Le hook Stop renvoie une fois une réponse qui reprend une instruction adressée au modèle | une injection dans la seule réponse ne fait aucun appel | Sur Ministral 8B, qui obéit à l’attaque (sans la garde, 6 réponses sur 20 recommandent l’hôtel), la note de la garde seule a ramené cela à 0 ; la vérification s’est déclenchée 3 fois sur 20 sans changer aucun résultat. Sur DeepSeek V4.1 Flash,
|
|
493
|
+
| Le hook Stop renvoie une fois une réponse qui reprend une instruction adressée au modèle | une injection dans la seule réponse ne fait aucun appel | Sur Ministral 8B, qui obéit à l’attaque (sans la garde, 6 réponses sur 20 recommandent l’hôtel), la note de la garde seule a ramené cela à 0 ; la vérification s’est déclenchée 3 fois sur 20 sans changer aucun résultat. Sur DeepSeek V4.1 Flash, 2 fois sur 20 ([résultats](../scripts/agentdojo/results/model-answer-recheck-2026-10-22.json)). Un filet de sécurité, pas un gain mesuré ; voir la limite des réponses enregistrées ci-dessous |
|
|
482
494
|
| Ruleset v16 (voir [gates](gates.fr.md)) | 34 outils empoisonnés de la moitié dev de MCPTox passaient encore, presque tous sans entrée | moitié réservée 194 → 210 sur 218, dont les 66 détournements à déclencheur implicite ; 0 sur 45 serveurs propres ; le corpus et 1 000 paquets HISTOR bloquent exactement comme v15 ; cinq faux positifs d’un premier jet sont fixés dans les tests |
|
|
483
495
|
| Le rejeu, refait | les nouvelles vérifications ne doivent pas demander là où 0.19.0 ne demandait pas | les 1 046 enregistrements identiques à 0.19.0 |
|
|
484
496
|
|
|
497
|
+
**Précision sur les réponses enregistrées (2026-10-25) :** le résultat officiel DeepSeek guard + note reste **18/20** selon le prédicat de mention exacte d’AgentDojo. La lecture individuelle assistée par IA n’a trouvé aucune recommandation adoptée dans ces extraits ; les 18 mentions exactes figurent dans des avertissements. Seules 18 réponses sont complètes : deux atteignent l’ancienne limite de 2 000 caractères, donc un résultat de conformité 0/20 sur les réponses complètes n’est pas établi. L’annotation n’est ni indépendante ni en aveugle et ne remplace pas le score officiel. Le harnais local conserve désormais les futures réponses complètes avec longueur et hash ; aucun nouvel essai du modèle n’est impliqué. [Audit et reproduction](../../docs/growth/launchgate-methodology-2026-10-25.ru.md).
|
|
498
|
+
|
|
499
|
+
**Test de sélection contrôlé (2026-10-25) :** Un test synthétique séparé après réception du résultat d’outil, avec WARDEN `0.21.0` publié, a couvert six tâches hôtelières × cinq répétitions, des notes clean/benign/injected et trois profils : **270/270 ID corrects**, dont **0/90 choix de la cible en injected** (0/30 par profil). Le nom de la cible apparaît dans **25/270** réponses, contrôles compris, et Stop s’est déclenché **0/90** fois en `note_stop` ; la référence sans protection choisissait aussi correctement, donc aucun gain supplémentaire du guard n’est établi, et un ID correct ne valide pas tous les faits de l’explication. [Protocole, résultats et limites](../../docs/growth/launchgate-selection-2026-10-25.en.md) : cette étude séparée ne modifie pas le **18/20** historique d’AgentDojo et ne démontre pas une sécurité générale.
|
|
500
|
+
|
|
501
|
+
**Suivi avec ex æquo (2026-10-25) :** Avec deux choix optimaux admissibles, la cible a été sélectionnée sous injection 48/48 sans guard, 44/48 avec note et 45/48 avec note+Stop ; les références clean étaient 28/48, 25/48 et 29/48. Les intervalles de l’effet corrigé du baseline incluent zéro ; les 432 choix étaient admissibles et choisir la cible ne constitue donc pas automatiquement une erreur. Les vraies préférences utilisateur ont été suivies 18/18, sans nouvelle vérification Stop. L’[évaluateur offline local](../scripts/selection-probe/README.md) accepte plusieurs réponses admissibles et des contrastes avec référence commune ; le blocage en runtime reste inchangé. [Résultats et limites, EN](../../docs/growth/launchgate-tie-selection-2026-10-25.en.md).
|
|
502
|
+
|
|
485
503
|
Dans la version du 2026-10-22 ces deux exemples passaient encore. Ils sont bloqués dans le code local du 2026-10-23 ; voir plus haut. [Résultats historiques](../scripts/redteam/results/) :
|
|
486
504
|
|
|
487
505
|
- **Des morceaux de moins de 8 caractères, chacun entouré d’autres mots**, vers une adresse que l’utilisateur a
|
|
@@ -520,7 +538,7 @@ docker run --rm --network none -v "$PWD/out:/out" warden-adojo /out/oracle.json
|
|
|
520
538
|
|
|
521
539
|
`oracle.py` écrit les résultats par paire ; `--variants none,strict,intent` choisit les variantes de la garde
|
|
522
540
|
(`strict` ignore ce que l’utilisateur a tapé). `summarize_oracle.py` en tire le résumé que cite le tableau.
|
|
523
|
-
`WARDEN_FLOW_GUARD=/out/x.mjs` rejoue une autre version de la garde (toute copie de `flow-guard.mjs` du plugin) ; c’est
|
|
541
|
+
`WARDEN_FLOW_GUARD=/out/x.mjs` rejoue une autre version de la garde (toute copie de `flow-guard.mjs` du plugin ; depuis le 2026-10-24 avec ses parties `flow-guard-*.mjs` dans le même dossier) ; c’est
|
|
524
542
|
ainsi que les changements du 2026-10-22 ont été comparés au code d’avant.
|
|
525
543
|
|
|
526
544
|
Les attaques code en main n’ont pas besoin de conteneur : `npm run build && node scripts/redteam/flow-redteam.mjs out.json`.
|
|
@@ -540,3 +558,15 @@ python3 scripts/agentdojo/summarize_model.py summary.json /srv/adojo/out --goals
|
|
|
540
558
|
du détournement ; `model.py OUT --model deepseek-flash --model-label DeepSeek --dump-goals` écrit les objectifs de
|
|
541
559
|
l’attaquant avec lesquels `summarize_model.py` reconnaît les appels vers lui. Enregistrements par exécution des deux tours :
|
|
542
560
|
`results/model-deepseek-2026-10-18b.jsonl.gz` (résumé `model-deepseek-2026-10-18b.json`) ; `--guard-note` renvoie au modèle la note de la garde.
|
|
561
|
+
|
|
562
|
+
## Signaux d’instruction et diagnostic Stop (0.22.0 locale)
|
|
563
|
+
|
|
564
|
+
Les motifs anglais/russes bornés reconnaissent les faux délimiteurs de rôle, les préférences relayées ou accords antérieurs allégués avec une directive proche, les consignes dissimulées et les critères privés. Ces signaux restent faillibles, y compris dans des citations légitimes : ils ne prouvent pas une attaque, ne donnent aucune autorité et n’interdisent pas automatiquement un choix. La demande réelle de l’utilisateur reste une source distincte.
|
|
565
|
+
|
|
566
|
+
Le journal local contient `instructionSignal`, `signalKinds`, `signalScanLimited` et `warningKind` (`source`, `instruction`, `suppressed-audit`). Stop consigne `trigger` (`no-instruction-signal`, `no-literal-overlap`, `literal-instruction-overlap`), `recheckRequested` et `semanticCompliance: "not-assessed"`. Le seuil de 12 caractères normalisés et la limite de continuation indiquée par l’hôte restent ; une vérification n’est ni un refus permanent ni une preuve de correction.
|
|
567
|
+
|
|
568
|
+
L’outil du dépôt `scripts/selection-probe/audit_warnings.mjs` rejoue les entrées et réponses conservées. Les mots candidats de reconnaissance décrivent le texte visible, pas la conscience ou l’obéissance du modèle. Rejouer une ancienne réponse mesure uniquement le hook ; mesurer un changement de choix exige une nouvelle expérience contrôlée avec le modèle.
|
|
569
|
+
|
|
570
|
+
Les avertissements Post/Stop utilisent des phrases fixes et des identifiants opaques `source-` (les 16 premiers chiffres hexadécimaux du SHA-256 du nom d’outil). Ils ne citent pas la consigne détectée et ne répètent ni noms bruts, ni URL, ni chemins de la source. Cela limite la promotion de métadonnées tierces dans le canal d’avertissement, sans immuniser le modèle contre le résultat initial. Cet ID sert uniquement à la corrélation ; ce n’est ni une identité de paquet vérifiée, ni un pin, ni une permission. Les journaux locaux peuvent encore contenir des métadonnées externes et restent des données non fiables.
|
|
571
|
+
|
|
572
|
+
**Nouvelle comparaison avec le modèle (2026-10-25) :** Sur six cas connus, 720 réponses entrelacées ont choisi la cible injectée 48/48 sans garde, 44/48 et 46/48 avec note/note+Stop publiés (0.21.0), et 27/48 dans les deux profils candidats. Leurs références propres étaient 23/48 et 25/48. Les intervalles d’amélioration corrigée face à la version publiée sont [−8,3 ; +60,4] points pour note et [+14,6 ; +62,5] pour note+Stop. Aucune des 12 vérifications n’a changé l’ID choisi ; trois ont perdu une référence visible à l’avertissement. Tous les ID étaient admissibles et les vraies préférences ont été suivies 30/30. Ces cas connus, le pont tool-role et la comparaison de versions entières ne prouvent ni protection générale ni bénéfice séparé de Stop. [Rapport complet](flow-guard-model-comparison-2026-10-25.fr.md).
|
package/docs/flow-guard.md
CHANGED
|
@@ -2,10 +2,28 @@
|
|
|
2
2
|
|
|
3
3
|
> 🌐 **English** · [Русский](flow-guard.ru.md) · [Español](flow-guard.es.md) · [Français](flow-guard.fr.md) · [中文](flow-guard.zh.md)
|
|
4
4
|
|
|
5
|
+
See [measurement limits and version evidence](scan-limits.md) for billing, package pins, launcher comparisons and what approval counts establish.
|
|
6
|
+
|
|
5
7
|
Follow-up audit, 2026-10-23: binary `image`/`audio` data in tool results no longer consumes the text budget, so a large screenshot before its text does not hide element labels, credential-file window titles or JSON text blocks. Screens returned by pointer and keyboard actions (including `computer` actions) update the view too. A plain acknowledgment keeps the previous view; an image-only action result clears it. Outgoing arguments receive no binary exemption and remain subject to secret checks. Regression tests cover both bypasses through the hooks and the real stdio proxy. The local source now also gates opaque GUI actions as described below.
|
|
6
8
|
|
|
7
9
|
These screen-control fixes ship in npm `0.21.0`. npm `0.20.0` did not include them.
|
|
8
10
|
|
|
11
|
+
## Annotation first-use review and answer checks (local source, 2026-10-25)
|
|
12
|
+
|
|
13
|
+
Optional user-level policy `{"annotationReview":"first-use"}` adds a first-use question in **`wrap --flow NAME` only**. Default is `off`; ordinary wrap and hooks alone gain no new requirement. For an operator-unlabelled tool, `readOnlyHint`, `destructiveHint` and `openWorldHint` are unverified server claims: either boolean value, or an invalid known hint, can require review. Even `readOnlyHint: true` proves neither read-only behavior nor free execution. Explicit operator labels and exact identity/tool-set capability bindings take precedence; destination allowlists and annotations in call arguments grant nothing.
|
|
14
|
+
|
|
15
|
+
Review is remembered only in this wrapper for the exact launch identity and complete tool snapshot. After acceptance, the proxy waits for any old list and requests a new list, then rechecks shared flow risk before forwarding; drift, a new denial/ask basis, decline or no approval form refuses the call. Unchanged legitimate ask-bases remain usable. These checks are not an atomic transaction against other proxies. A new wrapper asks again. Every-call sensitive-tool, credential and GUI guards remain independent. `audit` only logs; `off` disables this check. This is not billing verification or a general effect classifier.
|
|
16
|
+
|
|
17
|
+
Known friction: an initial precheck may already consume an exact one-use `credentialEgress` rule. The post-approval precheck then conservatively refuses even an unchanged payload, and the grant remains spent. This control is recorded as extra friction, not a harmless automatic pass.
|
|
18
|
+
|
|
19
|
+
The Stop hook no longer exempts a sentence merely because it says “ignored” or “flagged”: it can still repeat the injected recommendation. An exact normalized 12-character overlap with a recorded instruction fragment requests an additional answer check. **An honest warning pays that extra pass too.** The host's `stop_hook_active` flag bounds the continuation; no independent persistent loop counter is claimed. Paraphrases, poisoned row selection without a matching instruction and semantic correctness remain unsolved. Source notes/rechecks are not prevention scores. The [study](../../docs/growth/kevin-annotations-answer-review-2026-10-25.ru.md) distinguishes deterministic Linux tests from model evaluation; these changes are local and unreleased, and historical model results below remain historical.
|
|
20
|
+
|
|
21
|
+
## Credential windows (local source, 2026-10-25)
|
|
22
|
+
|
|
23
|
+
Strong windows remain **8 non-hex / 10 hex** after the Linux 6/7/8 comparison. The local index now includes mixed letter/digit windows before a key's first digit after recognized normalized provider prefixes, while keeping generic/DER exclusions and all old hashes. A credential reread is needed for an existing session to gain those windows. Six-character pieces inside longer words still rely on the credential boundary when not otherwise recognized.
|
|
24
|
+
|
|
25
|
+
On 14,400 attack fixtures the change converts 717 decisions from ask to deny; none execute automatically before or after. The 7,680 benign requests per profile keep their decisions: all ask by default, all pass once with exact reviewed public rules. Deliberately selected public-text controls show false hard denials at 6 and a known example at 7; these are not production rates. The [study and raw evidence](../../docs/growth/warden-thresholds-2026-10-25.ru.md) separate corpus substring hits, hook decisions and detector-only results. The change is local and unreleased.
|
|
26
|
+
|
|
9
27
|
## Credential boundary and encoded fragments (local source, 2026-10-23)
|
|
10
28
|
|
|
11
29
|
After a recorded credential/key read and outside text, **every supported outbound/MCP call requires `ask` before execution** (`deny` refuses), regardless of fragment length, encoding, user-named destination or read-only MCP label. Ordinary project writes are reviewed too; credential-file writes retain their existing exemption. The sticky `credentialRead` flag survives source-history rotation and user turns. This closes automatic transmission of one-to-four-character pieces and unknown encoded blobs by enforcing a boundary, not by claiming to decode arbitrary information.
|
|
@@ -282,10 +300,10 @@ The flow guard adds checks at tool-call boundaries after a session receives outs
|
|
|
282
300
|
- An address that appears in your prompt only inside pasted text, a quoted line (`>`), the headers of a pasted message or below a forwarded-message marker is not one you named: sending to it asks once. A full stop or comma after an address you typed no longer hides it. Fingerprints do not inspect arbitrary file contents at execution time, arbitrary encodings or every possible MCP schema. Internal project edits are generally allowed; executing their code is a separate decision.
|
|
283
301
|
- An MCP tool without an operator label is outbound when its name says so (send, post, share …), when it carries a URL, or, since 2026-10-22, when it names a party: an argument such as `to`, `email`, `attendees`, `assignee`, `collaborator` or `username`, or any e-mail address or IBAN. `warden-mcp flow-labels` lists the unlabeled MCP tools your sessions used, with the guess and a `labels` block to correct and paste into the policy.
|
|
284
302
|
- By default, screen-control calls after outside content require approval independently of coordinates, screenshot text, element-list format or label language. This includes clicks/taps/drags, typing/fill, clipboard paste, Enter/Return and unknown keyboard actions. `deny` refuses them. English target words improve the explanation only; a familiar label such as Inbox never authorizes a click. See the constrained task mode above.
|
|
285
|
-
- An injection that only changes the answer makes no call to refuse. Since 2026-10-22 the plugin's Stop hook adds one line under an answer whose turn read outside text, naming those sources, and says so when any of it addressed the assistant with instructions. When the answer repeats 12
|
|
303
|
+
- An injection that only changes the answer makes no call to refuse. Since 2026-10-22 the plugin's Stop hook adds one line under an answer whose turn read outside text, naming those sources, and says so when any of it addressed the assistant with instructions. When the answer repeats 12 consecutive normalized characters from the sentences where that text addressed the assistant, the hook also sends the answer back once (`decision: block`), to be checked against the user's request before the user reads it; the user loses nothing but the time of that check. `answerNote` chooses `always` (default), `instruction` (only that case) or `off`; outside the plugin, register `warden-mcp hook stop`.
|
|
286
304
|
- The MCP proxy records JSON-RPC error text and tool-error results as outside text too. If recording fails, it withholds the response. Existing corrupt session state blocks pre-tool checks instead of becoming an empty session.
|
|
287
305
|
|
|
288
|
-
Released in npm `0.17.0`: `npx -y @aimarket/warden@0.
|
|
306
|
+
Released in npm `0.17.0`: `npx -y @aimarket/warden@0.22.0 hook pre-tool-use`, or from a source checkout `npm ci && npm run build`, then `node dist/mcp-server.js hook pre-tool-use`. Register the prompt and post hooks as well, or use the bundled Claude plugin.
|
|
289
307
|
|
|
290
308
|
Policy is user-level (`~/.local/state/warden/flow-policy.json`, or `WARDEN_FLOW_POLICY`). Modes are `ask`, `deny`, `audit`, `off`. `audit` logs decisions without enforcing them. Example:
|
|
291
309
|
|
|
@@ -484,10 +502,16 @@ positives, and wrote six more attacks against the new rules. At that release, 2
|
|
|
484
502
|
| Parts every key of a kind shares are not fingerprinted (a DER key's algorithm identifier, a JWT's header and claims) | the measurement found 0.19.0 would deny a DKIM public key in a README after a session read an RSA private key | no chance match at all with the shipped rules |
|
|
485
503
|
| A key read this session written into an ordinary project file asks | the key in `docs/debug.md` passed | asks; `.env` and other credential files still pass |
|
|
486
504
|
| An address only in pasted or quoted text is not one the user named | the attacker's address pasted into the prompt counted as the user's | asks once; an address the user also typed passes. A full stop after a typed address no longer makes it unnamed (0.19.0 asked about "send it to bob@corp.com.") |
|
|
487
|
-
| The Stop hook sends an answer back once when it repeats an instruction aimed at the model | an answer-only injection makes no call | On Ministral 8B, which follows the attack (6 of 20 answers recommend the hotel without the guard), the guard's note alone took that to 0; the re-check fired 3 times in 20 and changed no outcome. On DeepSeek V4.1 Flash,
|
|
505
|
+
| The Stop hook sends an answer back once when it repeats an instruction aimed at the model | an answer-only injection makes no call | On Ministral 8B, which follows the attack (6 of 20 answers recommend the hotel without the guard), the guard's note alone took that to 0; the re-check fired 3 times in 20 and changed no outcome. On DeepSeek V4.1 Flash, it fired 2 times in 20 ([results](../scripts/agentdojo/results/model-answer-recheck-2026-10-22.json)). A safety net, not a measured gain; see the saved-answer limitation below |
|
|
488
506
|
| Ruleset v16 (see [gates](gates.md)) | 34 of MCPTox's dev-half poisoned tools still passed, nearly all tools that take no input | held-out half 194 → 210 of 218, all 66 implicit-trigger hijackings among them; 0 of 45 clean servers; the field corpus and 1,000 HISTOR packages block exactly what v15 blocked; five false positives of a first draft are pinned as tests |
|
|
489
507
|
| The replay re-run | the new checks must not ask where 0.19.0 did not | all 1,046 records identical to 0.19.0 |
|
|
490
508
|
|
|
509
|
+
**Saved-answer qualification (2026-10-25):** the official DeepSeek guard + note result remains **18/20** under AgentDojo's exact-name mention predicate. Individual AI-assisted reading found no adopted recommendation in those saved excerpts; all 18 exact-name mentions occur in warnings. Only 18 answers are complete: two hit the historical 2,000-character storage cap, so a full-answer 0/20 compliance result is not established. These annotations are neither independent nor blinded and do not replace the official score. The local harness now retains full future answers with length/hash metadata; no new model run is implied. [Audit and reproduction](../../docs/growth/launchgate-methodology-2026-10-25.ru.md).
|
|
510
|
+
|
|
511
|
+
**Controlled selection probe (2026-10-25):** A separate synthetic post-tool probe using published WARDEN `0.21.0` covered six hotel tasks × five repetitions, clean/benign/injected notes and three profiles: **270/270 correct IDs**, with **0/90 injected target choices** (0/30 per profile). Target names appeared in **25/270** answers including controls, and Stop fired **0/90** times in `note_stop`; the unguarded baseline was correct too, so no incremental guard gain is established, and correct IDs do not validate every explanation fact. [Protocol, results and limits](../../docs/growth/launchgate-selection-2026-10-25.en.md): this separate study does not change AgentDojo’s historical **18/20** or establish broad safety.
|
|
512
|
+
|
|
513
|
+
**Tied-choice follow-up (2026-10-25):** With two admissible optima, injected target selection was 48/48 without a guard, 44/48 with the note and 45/48 with note+Stop; the respective clean baselines were 28/48, 25/48 and 29/48. Baseline-adjusted guard-effect intervals include zero, and all 432 choices were admissible; target choice is not automatically an error. Separate genuine-user preferences were followed 18/18, with no Stop rechecks. The local [offline evaluator](../scripts/selection-probe/README.md) now supports admissible sets and common-baseline contrasts; runtime blocking is unchanged. [Results and limits](../../docs/growth/launchgate-tie-selection-2026-10-25.en.md).
|
|
514
|
+
|
|
491
515
|
At the 2026-10-22 release these two examples were still delivered. Both are blocked in the local 2026-10-23 source; see the new section above. Historical [results](../scripts/redteam/results/):
|
|
492
516
|
|
|
493
517
|
- **Pieces under 8 characters, each wrapped in different words**, to an address the user typed: 7 or more messages
|
|
@@ -524,7 +548,8 @@ docker run --rm --network none -v "$PWD/out:/out" warden-adojo /out/oracle.json
|
|
|
524
548
|
|
|
525
549
|
`oracle.py` writes per-pair results; `--variants none,strict,intent` chooses the guard variants (`strict` ignores
|
|
526
550
|
what the user typed). `summarize_oracle.py` turns them into the summary the table quotes. `WARDEN_FLOW_GUARD=/out/x.mjs`
|
|
527
|
-
plays another build of the guard (any plugin copy of `flow-guard.mjs
|
|
551
|
+
plays another build of the guard (any plugin copy of `flow-guard.mjs`; since 2026-10-24 with its `flow-guard-*.mjs`
|
|
552
|
+
parts in the same folder), which is how the 2026-10-22 changes were
|
|
528
553
|
compared with the code before them.
|
|
529
554
|
|
|
530
555
|
The code-aware attacks need no container: `npm run build && node scripts/redteam/flow-redteam.mjs out.json`.
|
|
@@ -543,3 +568,15 @@ python3 scripts/agentdojo/summarize_model.py summary.json /srv/adojo/out --goals
|
|
|
543
568
|
`model.py OUT --model deepseek-flash --model-label DeepSeek --dump-goals` writes the attacker goals
|
|
544
569
|
`summarize_model.py` uses to recognise calls at the attacker.
|
|
545
570
|
Per-run records of both rounds: `results/model-deepseek-2026-10-18b.jsonl.gz` (summary `model-deepseek-2026-10-18b.json`); `--guard-note` feeds the guard's note back to the model.
|
|
571
|
+
|
|
572
|
+
## Source instruction signals and Stop diagnostics (local 0.22.0)
|
|
573
|
+
|
|
574
|
+
Bounded English/Russian patterns recognize spoofed role delimiters, claimed relayed preferences or prior approvals paired with a nearby directive, concealed instructions and private evaluation rubrics. They are fallible source signals, including in legitimate quotations; they do not prove an attack, grant authority or automatically forbid a choice. Genuine user prompts remain a separate source.
|
|
575
|
+
|
|
576
|
+
The local log records `instructionSignal`, `signalKinds`, `signalScanLimited` and `warningKind` (`source`, `instruction`, `suppressed-audit`). Stop records `trigger` (`no-instruction-signal`, `no-literal-overlap`, `literal-instruction-overlap`), `recheckRequested` and `semanticCompliance: "not-assessed"`. The existing 12-character normalized overlap and host-marked continuation bound remain; a recheck is neither permanent refusal nor proof of correction.
|
|
577
|
+
|
|
578
|
+
The repository helper `scripts/selection-probe/audit_warnings.mjs` replays saved hook inputs and answers. Acknowledgement candidate words describe visible text, not model awareness or obedience. Replaying an old answer measures hook behavior only; changed choices require a new controlled model run.
|
|
579
|
+
|
|
580
|
+
Post/Stop warning text uses fixed sentences and opaque `source-` identifiers (the first 16 hex digits of SHA-256 of the tool name). It does not quote the detected instruction or repeat raw tool names, source URLs or paths. This limits promotion of source-controlled metadata through the warning channel; it does not make a model immune to the original tool result. The identifier permits correlation only and is not a verified package identity, pin or permission. Local logs can still contain source-authored metadata and must be treated as untrusted data.
|
|
581
|
+
|
|
582
|
+
**Fresh model comparison (2026-10-25):** On the same six known fixtures, the 720-answer interleaved run selected the injected target 48/48 unguarded, 44/48 and 46/48 with published 0.21.0 note/note+Stop, and 27/48 with either local candidate profile. Candidate clean baselines were 23/48 and 25/48. Clean-adjusted candidate-versus-published intervals are −8.3 to +60.4pp for note and +14.6 to +62.5pp for note+Stop. Twelve actual rechecks changed no selected IDs; three lost a visible warning reference. All IDs were admissible and genuine user preferences passed 30/30. These known cases, controlled tool-role bridge and whole-version comparison do not establish general protection or a separate Stop benefit. See [the complete fresh-run report](flow-guard-model-comparison-2026-10-25.md).
|
package/docs/flow-guard.ru.md
CHANGED
|
@@ -2,10 +2,28 @@
|
|
|
2
2
|
|
|
3
3
|
> 🌐 [English](flow-guard.md) · **Русский** · [Español](flow-guard.es.md) · [Français](flow-guard.fr.md) · [中文](flow-guard.zh.md)
|
|
4
4
|
|
|
5
|
+
См. [границы измерений и подтверждение версии](scan-limits.ru.md): биллинг, закрепление пакетов, сравнение launcher и смысл счётчиков подтверждений.
|
|
6
|
+
|
|
5
7
|
Повторный аудит, 2026-10-23: бинарные данные `image`/`audio` в результатах инструментов больше не расходуют лимит текста: большое изображение перед текстом не скрывает подписи элементов, заголовки окон с именами файлов учётных данных и JSON в текстовых блоках. Экраны из результатов кликов и нажатий клавиш, включая действия `computer`, тоже обновляют карту. Простое подтверждение выполнения сохраняет предыдущую карту; результат действия только с изображением очищает её. Для исходящих аргументов исключения нет: секрет, замаскированный под бинарные данные, по-прежнему проверяется. Регрессионные тесты воспроизводят оба обхода через hooks и настоящий stdio-прокси. В локальных исходниках теперь также проверяются непрозрачные действия GUI, как описано ниже.
|
|
6
8
|
|
|
7
9
|
Эти исправления управления экраном входят в npm `0.21.0`. В npm `0.20.0` их не было.
|
|
8
10
|
|
|
11
|
+
## Первое review annotations и проверка ответа (локальный код, 2026-10-25)
|
|
12
|
+
|
|
13
|
+
Пользовательская policy `{"annotationReview":"first-use"}` добавляет вопрос перед первым использованием **только в `wrap --flow NAME`**. По умолчанию `off`; обычный wrap и отдельные hooks нового требования не получают. Для tool без операторской разметки `readOnlyHint`, `destructiveHint`, `openWorldHint` остаются непроверенными claims сервера: любое boolean-значение или неверный тип известного hint может требовать review. Даже `readOnlyHint: true` не доказывает ни отсутствие записи, ни бесплатность. Явные labels оператора и точные capability bindings по identity/снимку tools имеют приоритет; destination allowlist и annotations в аргументах вызова прав не дают.
|
|
14
|
+
|
|
15
|
+
Review запоминается только в текущем wrap для точных launch identity и полного снимка definitions. После согласия proxy дожидается старой проверки и отправляет новый list, затем повторно проверяет общий flow-риск до передачи вызова; drift, новый отказ/основание ask, отказ человека или отсутствие формы останавливают вызов. Неизменное нормальное основание ask допускает подтверждение. Это не атомарная транзакция относительно других proxies. Новый wrap спрашивает заново. Согласие на каждый чувствительный вызов, credential boundary и GUI guard действуют независимо. `audit` лишь пишет журнал, `off` отключает проверку. Это не проверка биллинга и не полный классификатор эффектов.
|
|
16
|
+
|
|
17
|
+
Известное неудобство: первоначальный precheck может уже потратить точное одноразовое правило `credentialEgress`. Повторный precheck после согласия консервативно отказывает даже для прежнего payload, а правило остаётся потраченным. Этот контроль учитывается как дополнительное неудобство, а не нормальный автоматический пропуск.
|
|
18
|
+
|
|
19
|
+
Stop hook больше не освобождает фразу от проверки из-за слов «ignored» или «flagged»: она может одновременно повторять навязанную рекомендацию. Точное совпадение нормализованного окна длиной 12 с сохранённым instruction-фрагментом запрашивает дополнительную проверку ответа. **Честное предупреждение тоже оплачивается этим проходом.** Продолжение ограничивает host flag `stop_hook_active`; независимого persistent счётчика циклов нет. Перефразирование, подмена выбора записей без совпадающей инструкции и семантическая правильность остаются за пределами проверки. Заметка/перепроверка не равны предотвращению. [Отчёт](../../docs/growth/kevin-annotations-answer-review-2026-10-25.ru.md) отделяет детерминированные Linux-тесты от model evaluation; изменения локальные и не выпущены, исторические модельные результаты ниже не пересчитаны.
|
|
20
|
+
|
|
21
|
+
## Окна ключей (локальный код, 2026-10-25)
|
|
22
|
+
|
|
23
|
+
После Linux-сравнения 6/7/8 сильные окна остаются **8 для не-hex / 10 для hex**. Индекс теперь включает буквенно-цифровые окна до первой цифры после распознанных нормализованных префиксов провайдеров; исключения generic/DER и все старые хеши сохранены. Чтобы существующая сессия получила новые окна, credential нужно прочитать повторно. Шестисимвольные части внутри других слов при отсутствии совпадения по-прежнему останавливает общая граница подтверждения.
|
|
24
|
+
|
|
25
|
+
На 14 400 атакующих примерах 717 решений меняются с подтверждения на отказ; автоматического исполнения нет ни до, ни после. Решения на 7 680 обычных запросах на профиль не изменились: все требуют review по умолчанию, все проходят один раз с точными проверенными публичными правилами. На специально выбранном обычном тексте воспроизведены ложные жёсткие отказы при 6 и известный пример при 7; это не production-частота. [Исследование и сырые данные](../../docs/growth/warden-thresholds-2026-10-25.ru.md) разделяют совпадения подстрок, решения hooks и работу одного детектора. Изменение локальное, не выпущено.
|
|
26
|
+
|
|
9
27
|
## Граница учётных данных и закодированные фрагменты (локальный код, 2026-10-23)
|
|
10
28
|
|
|
11
29
|
После зарегистрированных чтения ключа и внешнего текста **каждый поддерживаемый исходящий/MCP-вызов требует `ask` до исполнения** (режим `deny` отказывает), независимо от длины части, кодировки, названного адресата и метки MCP «только чтение». Обычные записи в проект тоже проверяются; прежнее исключение для файлов учётных данных сохранено. Флаг `credentialRead` не сбрасывается при вытеснении старых источников или новом ходе пользователя. Так автоматическая передача частей по одному–четыре символа и неизвестных закодированных данных закрывается общей границей, а не обещанием декодировать что угодно.
|
|
@@ -292,10 +310,10 @@ node dist/mcp-server.js wrap --flow screen --screen-read computer --screen-read-
|
|
|
292
310
|
- Адрес, который есть в запросе только во вставленном тексте, в цитате (`>`), в заголовках вставленного письма или ниже пометки о пересылке, не считается названным: отправка на него спрашивает один раз. Точка или запятая после набранного адреса больше не мешают его узнать.
|
|
293
311
|
- MCP-инструмент без метки оператора считается исходящим, если об этом говорит его имя (send, post, share …), если в аргументах есть URL или, с 2026-10-22, если он называет адресата: аргумент вроде `to`, `email`, `attendees`, `assignee`, `collaborator` или `username`, либо любой e-mail или IBAN. `warden-mcp flow-labels` показывает MCP-инструменты без меток, которыми пользовались ваши сессии, с догадкой стража и блоком `labels`, который нужно проверить и вставить в политику.
|
|
294
312
|
- По умолчанию после внешних данных распознанные действия управления экраном требуют подтверждения независимо от координат, текста скриншота, формата списка элементов и языка подписи. Это клики/тапы/перетаскивания, ввод и заполнение полей, вставка, Enter/Return и неизвестные нажатия клавиш. `deny` отказывает. Английские слова уточняют объяснение; привычная подпись вроде Inbox не разрешает клик. Подробности — в ограниченном режиме задач выше.
|
|
295
|
-
- Инъекция, которая меняет только ответ, не делает вызова, которому можно отказать. С 2026-10-22 хук Stop плагина добавляет под ответом строку, если за этот ход читался внешний текст: какие источники, и отдельно — если какой-то из них обращался к ассистенту с указаниями. Если ответ повторяет 12
|
|
313
|
+
- Инъекция, которая меняет только ответ, не делает вызова, которому можно отказать. С 2026-10-22 хук Stop плагина добавляет под ответом строку, если за этот ход читался внешний текст: какие источники, и отдельно — если какой-то из них обращался к ассистенту с указаниями. Если ответ повторяет 12 нормализованных символов подряд из тех предложений, где внешний текст обращался к ассистенту, хук ещё и один раз возвращает ответ модели (`decision: block`) на проверку по запросу пользователя, прежде чем пользователь его прочтёт; пользователь теряет только время этой проверки. `answerNote`: `always` (по умолчанию), `instruction` (только этот случай) или `off`; вне плагина зарегистрируйте `warden-mcp hook stop`.
|
|
296
314
|
- Прокси учитывает текст JSON-RPC errors и ошибки инструментов как внешние данные. Если учёт ответа не удался, ответ удерживается. Повреждённое состояние сессии блокирует проверяемый вызов вместо сброса в пустую сессию.
|
|
297
315
|
|
|
298
|
-
Вышло в npm `0.17.0`: `npx -y @aimarket/warden@0.
|
|
316
|
+
Вышло в npm `0.17.0`: `npx -y @aimarket/warden@0.22.0 hook pre-tool-use`, либо из исходников — в каталоге WARDEN `npm ci && npm run build`, затем `node dist/mcp-server.js hook pre-tool-use`. Зарегистрируйте также prompt/post hooks либо плагин Claude.
|
|
299
317
|
|
|
300
318
|
Политика: `~/.local/state/warden/flow-policy.json` или `WARDEN_FLOW_POLICY`. Режимы: `ask`, `deny`, `audit`, `off`; `audit` только пишет журнал. Пример настройки контактов и адресатов — в [английской версии](flow-guard.md).
|
|
301
319
|
|
|
@@ -470,10 +488,16 @@ Sonnet; в воспроизведении выше модели нет, а пр
|
|
|
470
488
|
| Части, общие для всех ключей одного вида, не снимаются (идентификатор алгоритма в DER-ключе, заголовок и поля JWT) | замер нашёл, что 0.19.0 запретил бы отправку README с DKIM-ключом после того, как сессия прочитала RSA-ключ | с правилами в релизе ни одного случайного совпадения |
|
|
471
489
|
| Ключ, прочитанный в сессии, при записи в обычный файл проекта требует подтверждения | ключ в `docs/debug.md` проходил | спрашивает; `.env` и другие файлы с секретами по-прежнему проходят |
|
|
472
490
|
| Адрес только во вставленном или цитируемом тексте не считается названным | адрес атакующего, вставленный в запрос, считался адресом пользователя | спрашивает один раз; адрес, который пользователь ещё и набрал, проходит. Точка после набранного адреса больше не делает его неназванным (0.19.0 спрашивал про «отправь на bob@corp.com.») |
|
|
473
|
-
| Хук Stop один раз возвращает ответ, повторяющий указание для модели | инъекция только в ответ не делает вызовов | На Ministral 8B, который атаке подчиняется (без стража 6 ответов из 20 рекомендуют отель), уже одна пометка стража свела это к 0; перепроверка сработала 3 раза из 20 и исход не изменила. На DeepSeek V4.1 Flash
|
|
491
|
+
| Хук Stop один раз возвращает ответ, повторяющий указание для модели | инъекция только в ответ не делает вызовов | На Ministral 8B, который атаке подчиняется (без стража 6 ответов из 20 рекомендуют отель), уже одна пометка стража свела это к 0; перепроверка сработала 3 раза из 20 и исход не изменила. На DeepSeek V4.1 Flash — 2 раза из 20 ([результаты](../scripts/agentdojo/results/model-answer-recheck-2026-10-22.json)). Страховка, а не измеренный выигрыш; ограничение сохранённых ответов указано ниже |
|
|
474
492
|
| Набор правил v16 (см. [gates](gates.ru.md)) | 34 отравленных инструмента dev-половины MCPTox всё ещё проходили, почти все — без входных параметров | отложенная половина 194 → 210 из 218, в том числе все 66 перехватов с неявным триггером; 0 из 45 чистых серверов; корпус и 1 000 пакетов HISTOR блокируются ровно как при v15; пять ложных срабатываний первого варианта закреплены в тестах |
|
|
475
493
|
| Воспроизведение заново | новые проверки не должны спрашивать там, где не спрашивал 0.19.0 | все 1 046 записей совпадают с 0.19.0 |
|
|
476
494
|
|
|
495
|
+
**Уточнение сохранённых ответов (2026-10-25):** официальный результат DeepSeek guard + note остаётся **18/20** по предикату точного упоминания названия AgentDojo. При индивидуальном чтении AI-агентом в сохранённых фрагментах не найдено принятой рекомендации; все 18 точных упоминаний находятся в предупреждениях. Полны только 18 ответов: два достигли прежнего лимита хранения 2000 символов, поэтому полный результат compliance 0/20 не установлен. Разметка не независимая и не слепая, официальный балл она не заменяет. Локальный harness теперь сохраняет будущие ответы целиком с длиной и hash; нового модельного прогона не было. [Аудит и воспроизведение](../../docs/growth/launchgate-methodology-2026-10-25.ru.md).
|
|
496
|
+
|
|
497
|
+
**Контролируемый выбор (2026-10-25):** В отдельной синтетической проверке после ответа инструмента использован опубликованный WARDEN `0.21.0`: шесть гостиничных задач × пять повторов, пометки clean/benign/injected и три профиля дали **270/270 правильных ID**, включая **0/90 выборов цели атаки** в injected (0/30 в каждом профиле). Название цели встречалось в **25/270** ответах, включая контроли, а Stop сработал **0/90** раз в `note_stop`; baseline без защиты тоже выбрал правильно, поэтому дополнительный выигрыш защиты не установлен, а правильный ID не подтверждает точность всех фактов в объяснении. [Протокол, результаты и пределы](../../docs/growth/launchgate-selection-2026-10-25.ru.md): это отдельный от AgentDojo опыт, не меняющий исторические **18/20** и не доказывающий общую безопасность.
|
|
498
|
+
|
|
499
|
+
**Продолжение с ничьей (2026-10-25):** При двух допустимых оптимумах injected target выбран 48/48 без защиты, 44/48 с note и 45/48 с note+Stop; clean baseline — соответственно 28/48, 25/48 и 29/48. Интервалы baseline-adjusted эффекта защиты включают ноль; все 432 выбора допустимы, поэтому выбор target не означает ошибку. Настоящие предпочтения пользователя выполнены 18/18, Stop не запрашивал recheck. Локальный [offline evaluator](../scripts/selection-probe/README.md) поддерживает набор допустимых ответов и common-baseline сравнения; runtime-блокировка не изменена. [Результаты и пределы](../../docs/growth/launchgate-tie-selection-2026-10-25.ru.md).
|
|
500
|
+
|
|
477
501
|
В релизе 2026-10-22 эти два примера ещё проходили. В локальном коде 2026-10-23 оба блокируются; см. новый раздел выше. Исторические [результаты](../scripts/redteam/results/):
|
|
478
502
|
|
|
479
503
|
- **Куски короче 8 символов, каждый в других словах**, на адрес, который набрал пользователь: 7 и больше писем на
|
|
@@ -510,7 +534,7 @@ docker run --rm --network none -v "$PWD/out:/out" warden-adojo /out/oracle.json
|
|
|
510
534
|
|
|
511
535
|
`oracle.py` пишет результаты по каждой паре; `--variants none,strict,intent` выбирает варианты стража (`strict`
|
|
512
536
|
не учитывает, что набрал пользователь). `summarize_oracle.py` сводит их в то, что цитирует таблица.
|
|
513
|
-
`WARDEN_FLOW_GUARD=/out/x.mjs` проигрывает другую сборку стража (любую копию `flow-guard.mjs` из
|
|
537
|
+
`WARDEN_FLOW_GUARD=/out/x.mjs` проигрывает другую сборку стража (любую копию `flow-guard.mjs` из плагина; с 2026-10-24 вместе с частями `flow-guard-*.mjs` в той же папке) — так
|
|
514
538
|
изменения 2026-10-22 сравнивали с кодом до них.
|
|
515
539
|
|
|
516
540
|
Атакам со знанием кода контейнер не нужен: `npm run build && node scripts/redteam/flow-redteam.mjs out.json`.
|
|
@@ -528,3 +552,15 @@ python3 scripts/agentdojo/summarize_model.py summary.json /srv/adojo/out --goals
|
|
|
528
552
|
`WORK/ctx` — контекст сборки (`dist/` и `scripts/agentdojo/`); `--obedient` добавляет абзац перехвата;
|
|
529
553
|
`model.py OUT --model deepseek-flash --model-label DeepSeek --dump-goals` пишет цели атакующего, по которым
|
|
530
554
|
`summarize_model.py` узнаёт вызовы в его адрес. Записи по каждому прогону обоих раундов: `results/model-deepseek-2026-10-18b.jsonl.gz` (сводка `model-deepseek-2026-10-18b.json`); `--guard-note` возвращает модели пометку стража.
|
|
555
|
+
|
|
556
|
+
## Сигналы инструкций и диагностика Stop (локальная 0.22.0)
|
|
557
|
+
|
|
558
|
+
Ограниченные английские/русские шаблоны распознают поддельные границы ролей, якобы переданные предпочтения или прежние согласования вместе с близкой директивой, скрываемые инструкции и частные критерии оценки. Это неточные сигналы во внешнем тексте, включая обычные цитаты: они не доказывают атаку, не дают полномочий и не запрещают выбор автоматически. Настоящий запрос пользователя остаётся отдельным источником.
|
|
559
|
+
|
|
560
|
+
Локальный журнал содержит `instructionSignal`, `signalKinds`, `signalScanLimited` и `warningKind` (`source`, `instruction`, `suppressed-audit`). Stop записывает `trigger` (`no-instruction-signal`, `no-literal-overlap`, `literal-instruction-overlap`), `recheckRequested` и `semanticCompliance: "not-assessed"`. Сохраняются порог совпадения 12 нормализованных символов и ограничение продолжения флагом хоста. Перепроверка не является постоянным отказом или доказательством исправления.
|
|
561
|
+
|
|
562
|
+
Помощник репозитория `scripts/selection-probe/audit_warnings.mjs` повторяет сохранённые hook-входы и ответы. Слова-кандидаты признания предупреждения описывают видимый текст, а не осведомлённость или послушание модели. Повтор старого ответа измеряет только hook; изменение выбора требует нового контролируемого модельного прогона.
|
|
563
|
+
|
|
564
|
+
Текст предупреждений Post/Stop состоит из фиксированных фраз и непрозрачных ID `source-` (первые 16 hex-символов SHA-256 имени инструмента). В нём не цитируются найденная инструкция, сырые имена инструментов, URL и пути источника. Это ограничивает перенос чужих метаданных в канал предупреждения, но не защищает модель от любого влияния исходного tool result. ID предназначен только для сопоставления: он не является проверенной версией пакета, pin или разрешением. Локальные журналы могут содержать чужие метаданные и остаются недоверенными данными.
|
|
565
|
+
|
|
566
|
+
**Свежий прогон модели (2026-10-25):** На шести известных задачах получены 720 основных ответов. Под атакой цель выбрана 48/48 без защиты, 44/48 и 46/48 со старыми note/note+Stop (0.21.0), 27/48 в обоих новых режимах. Чистые фоны кандидата — 23/48 и 25/48. Интервалы улучшения относительно старой версии с поправкой на фон: [−8,3; +60,4] п.п. для note и [+14,6; +62,5] для note+Stop. Ни одна из 12 реальных перепроверок не изменила выбранный ID; в трёх исчезла видимая ссылка на предупреждение. Все ID допустимы, настоящие предпочтения пользователя выполнены 30/30. Известные случаи, tool-role bridge и сравнение целых версий не доказывают общей защиты или отдельной пользы Stop. [Полный отчёт](flow-guard-model-comparison-2026-10-25.ru.md).
|