@agentunion/fastaun-browser 0.5.0 → 0.5.2

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 (140) hide show
  1. package/CHANGELOG.md +550 -464
  2. package/_packed_docs/CHANGELOG-validators.md +147 -0
  3. package/_packed_docs/CHANGELOG.md +550 -464
  4. package/_packed_docs/INDEX.md +201 -177
  5. package/_packed_docs/KITE_DOCS_GUIDE.md +38 -32
  6. package/_packed_docs/agent.md//350/277/234/347/250/213agent.md/347/274/223/345/255/230/344/270/216etag/351/200/217/344/274/240/346/226/271/346/241/210.md +169 -116
  7. package/_packed_docs/aun-perf-audit-critical-bugs.md +315 -0
  8. package/_packed_docs/cli/AUN-CLI/350/256/276/350/256/241/346/226/207/346/241/243.md +263 -260
  9. package/_packed_docs/cli/CLI/346/211/213/345/206/214.md +331 -0
  10. package/_packed_docs/protocol/00-/346/200/273/350/247/210/344/270/216/345/210/206/345/261/202.md +2 -2
  11. package/_packed_docs/protocol/00A-/350/256/276/350/256/241/345/216/237/345/210/231-/344/270/272Agent/350/200/214/347/224/237.md +1 -1
  12. package/_packed_docs/protocol/01-/350/272/253/344/273/275/344/270/216/345/207/255/350/257/201/345/215/217/350/256/256-auth.md +39 -16
  13. package/_packed_docs/protocol/03-Gateway-/350/277/236/346/216/245/346/250/241/345/274/217.md +8 -5
  14. package/_packed_docs/protocol/06-/346/234/215/345/212/241/345/215/217/350/256/256.md +18 -19
  15. package/_packed_docs/protocol/07-/351/224/231/350/257/257/347/240/201/344/270/216/347/212/266/346/200/201/346/234/272.md +1 -1
  16. package/_packed_docs/protocol/08-AUN-E2EE-Group.md +139 -746
  17. package/_packed_docs/protocol/08-AUN-E2EE.md +12 -10
  18. package/_packed_docs/protocol/10-Group-/345/255/220/345/215/217/350/256/256.md +117 -171
  19. package/_packed_docs/protocol/11-Storage-/345/255/220/345/215/217/350/256/256.md +6 -0
  20. package/_packed_docs/protocol/15-/347/246/273/347/272/277/346/216/250/351/200/201/351/200/232/347/237/245/345/215/217/350/256/256.md +1 -1
  21. package/_packed_docs/protocol/16-/347/263/273/347/273/237/347/233/256/345/275/225/344/277/235/346/212/244/346/226/271/346/241/210.md +177 -0
  22. package/_packed_docs/protocol/README.md +5 -4
  23. package/_packed_docs/protocol/aun-docs-guide.md +2 -2
  24. package/_packed_docs/protocol/index.md +12 -7
  25. package/_packed_docs/protocol//350/215/211/346/241/210-/346/213/222/347/273/235/344/277/241/345/217/267/345/215/217/350/256/256.md +1 -1
  26. package/_packed_docs/protocol//351/231/204/345/275/225A-/346/234/257/350/257/255/350/241/250.md +13 -13
  27. package/_packed_docs/protocol//351/231/204/345/275/225L-E2EE/345/256/236/347/216/260/346/214/207/345/215/227.md +9 -9
  28. package/_packed_docs/sdk/02-WebSocket/345/215/217/350/256/256.md +15 -13
  29. package/_packed_docs/sdk/04-/350/277/236/346/216/245/344/270/216/350/256/244/350/257/201.md +26 -18
  30. package/_packed_docs/sdk/05-E2EE/345/212/240/345/257/206/351/200/232/344/277/241.md +35 -284
  31. package/_packed_docs/sdk/06-API/346/211/213/345/206/214.md +473 -442
  32. package/_packed_docs/sdk/07-/351/224/231/350/257/257/345/244/204/347/220/206.md +11 -7
  33. package/_packed_docs/sdk/09-collab-rpc-manual.md +581 -550
  34. package/_packed_docs/sdk/09-group-rpc-manual.md +367 -433
  35. package/_packed_docs/sdk/09-message-rpc-manual.md +50 -28
  36. package/_packed_docs/sdk/09-payload-reference.md +3 -3
  37. package/_packed_docs/sdk/09-storage-rpc-manual.md +57 -20
  38. package/_packed_docs/sdk/AUN_DOCS_GUIDE.md +18 -17
  39. package/_packed_docs/sdk/E2EE_V2/346/266/210/346/201/257/351/200/232/344/277/241/346/227/266/345/272/217/345/233/276.md +3 -2
  40. package/_packed_docs/sdk/INDEX.md +25 -24
  41. package/_packed_docs/sdk/Notify/351/200/232/347/237/245/346/226/271/346/241/210.md +6 -2
  42. package/dist/agent-md.d.ts.map +1 -1
  43. package/dist/agent-md.js +18 -9
  44. package/dist/agent-md.js.map +1 -1
  45. package/dist/bundle.js +1661 -1180
  46. package/dist/client/delivery.d.ts +13 -2
  47. package/dist/client/delivery.d.ts.map +1 -1
  48. package/dist/client/delivery.js +251 -46
  49. package/dist/client/delivery.js.map +1 -1
  50. package/dist/client/group-state.d.ts.map +1 -1
  51. package/dist/client/group-state.js +36 -14
  52. package/dist/client/group-state.js.map +1 -1
  53. package/dist/client/lifecycle.js +2 -2
  54. package/dist/client/lifecycle.js.map +1 -1
  55. package/dist/client/rpc-pipeline.d.ts +1 -0
  56. package/dist/client/rpc-pipeline.d.ts.map +1 -1
  57. package/dist/client/rpc-pipeline.js +166 -50
  58. package/dist/client/rpc-pipeline.js.map +1 -1
  59. package/dist/client/v2-e2ee.d.ts +14 -1
  60. package/dist/client/v2-e2ee.d.ts.map +1 -1
  61. package/dist/client/v2-e2ee.js +376 -126
  62. package/dist/client/v2-e2ee.js.map +1 -1
  63. package/dist/client.d.ts +5 -4
  64. package/dist/client.d.ts.map +1 -1
  65. package/dist/client.js +187 -46
  66. package/dist/client.js.map +1 -1
  67. package/dist/collab/client.d.ts +8 -0
  68. package/dist/collab/client.d.ts.map +1 -1
  69. package/dist/collab/client.js +12 -0
  70. package/dist/collab/client.js.map +1 -1
  71. package/dist/errors.d.ts +0 -20
  72. package/dist/errors.d.ts.map +1 -1
  73. package/dist/errors.js +8 -51
  74. package/dist/errors.js.map +1 -1
  75. package/dist/facades.d.ts +9 -4
  76. package/dist/facades.d.ts.map +1 -1
  77. package/dist/facades.js +192 -31
  78. package/dist/facades.js.map +1 -1
  79. package/dist/group-fs.d.ts +17 -0
  80. package/dist/group-fs.d.ts.map +1 -1
  81. package/dist/group-fs.js +54 -11
  82. package/dist/group-fs.js.map +1 -1
  83. package/dist/group-id.d.ts +9 -12
  84. package/dist/group-id.d.ts.map +1 -1
  85. package/dist/group-id.js +41 -63
  86. package/dist/group-id.js.map +1 -1
  87. package/dist/index.d.ts +4 -2
  88. package/dist/index.d.ts.map +1 -1
  89. package/dist/index.js +4 -1
  90. package/dist/index.js.map +1 -1
  91. package/dist/keystore/index.d.ts +2 -54
  92. package/dist/keystore/index.d.ts.map +1 -1
  93. package/dist/keystore/indexeddb-identity-store.d.ts +3 -0
  94. package/dist/keystore/indexeddb-identity-store.d.ts.map +1 -1
  95. package/dist/keystore/indexeddb-identity-store.js +65 -0
  96. package/dist/keystore/indexeddb-identity-store.js.map +1 -1
  97. package/dist/keystore/indexeddb-shared.d.ts +3 -17
  98. package/dist/keystore/indexeddb-shared.d.ts.map +1 -1
  99. package/dist/keystore/indexeddb-shared.js +4 -47
  100. package/dist/keystore/indexeddb-shared.js.map +1 -1
  101. package/dist/keystore/indexeddb-token-store.d.ts +1 -64
  102. package/dist/keystore/indexeddb-token-store.d.ts.map +1 -1
  103. package/dist/keystore/indexeddb-token-store.js +45 -774
  104. package/dist/keystore/indexeddb-token-store.js.map +1 -1
  105. package/dist/logger.d.ts +2 -0
  106. package/dist/logger.d.ts.map +1 -1
  107. package/dist/logger.js +4 -0
  108. package/dist/logger.js.map +1 -1
  109. package/dist/storage/lowlevel.d.ts +9 -1
  110. package/dist/storage/lowlevel.d.ts.map +1 -1
  111. package/dist/storage/lowlevel.js +12 -1
  112. package/dist/storage/lowlevel.js.map +1 -1
  113. package/dist/storage/vfs.d.ts +22 -0
  114. package/dist/storage/vfs.d.ts.map +1 -1
  115. package/dist/storage/vfs.js +54 -0
  116. package/dist/storage/vfs.js.map +1 -1
  117. package/dist/tools/cross-sdk-agent.js +336 -49
  118. package/dist/tools/cross-sdk-agent.js.map +1 -1
  119. package/dist/transport.d.ts +2 -0
  120. package/dist/transport.d.ts.map +1 -1
  121. package/dist/transport.js +96 -3
  122. package/dist/transport.js.map +1 -1
  123. package/dist/types.d.ts +39 -56
  124. package/dist/types.d.ts.map +1 -1
  125. package/dist/v2/session/session.d.ts +2 -0
  126. package/dist/v2/session/session.d.ts.map +1 -1
  127. package/dist/v2/session/session.js +58 -22
  128. package/dist/v2/session/session.js.map +1 -1
  129. package/dist/v2/state/commitment.d.ts +1 -1
  130. package/dist/v2/state/commitment.d.ts.map +1 -1
  131. package/dist/v2/state/commitment.js +5 -3
  132. package/dist/v2/state/commitment.js.map +1 -1
  133. package/dist/validators.d.ts +35 -0
  134. package/dist/validators.d.ts.map +1 -0
  135. package/dist/validators.js +127 -0
  136. package/dist/validators.js.map +1 -0
  137. package/dist/version.d.ts +1 -1
  138. package/dist/version.js +1 -1
  139. package/package.json +1 -1
  140. package/_packed_docs/collab-gateway-boundary-test-report.md +0 -164
@@ -0,0 +1,177 @@
1
+ # 16. 系统目录保护方案
2
+
3
+ ## 16.1 目标
4
+
5
+ `memberdata` 与 `group_data` 是 Group FS 与 Storage 协作使用的系统级目录名。它们不能被当作普通用户目录处理,否则会造成权限绕过、视图层与真实存储层混淆、误删成员数据和配额统计失真。
6
+
7
+ 本方案定义两个目录名的保护规则:
8
+
9
+ - `memberdata`:Group FS 视图层的虚拟协议目录。
10
+ - `group_data`:Storage 真实层的内部协议根目录。
11
+
12
+ 外部用户、SDK、CLI 和普通 `storage.*` / `storage.fs.*` RPC 只能看到业务语义,不应把真实存储根作为应用目录树入口。`group_data` 的存在不是保密目标;保护目标是目录树不展示系统根、普通写入不能绕过 `group.fs.*` 授权路径。
13
+
14
+ ## 16.2 目录分层
15
+
16
+ | 名称 | 所在层 | 示例 | 性质 | 对外可见性 |
17
+ | --- | --- | --- | --- | --- |
18
+ | `memberdata` | Group FS 视图层 | `group_aid:/memberdata/alice.aid/logs/a.md` | 虚拟目录和成员槽位边界 | 在 Group FS 中可见;普通 Storage 面不因目录名隐藏,但写保护 |
19
+ | `group_data` | Storage 真实层 | `member_aid:/group_data/{group_aid}/logs/a.md` | 内部真实存储根 | 普通 Storage 目录树隐藏;读/下载不刻意隐藏;写保护 |
20
+
21
+ `memberdata/{member_ref}` 映射到 `member_aid:/group_data/{group_aid}`。SDK 和 CLI 不得拼接 `group_data`;服务端 group 模块负责视图路径解析,storage 模块负责真实路径保护和配额统计。
22
+
23
+ ## 16.3 总体原则
24
+
25
+ 1. `memberdata` 根和成员槽位不是普通目录,不能被普通文件操作破坏。
26
+ 2. `memberdata` 不是隐藏目录;保护重点是禁止普通 Storage 写入 group AID 命名空间下的 `memberdata/...`。
27
+ 3. `group_data` 是保留真实根,普通 Storage 目录树浏览不展示它,普通 Storage 写入、删除、重命名、挂载、授权和状态变更必须拒绝。
28
+ 4. `group_data` 的对象读取、下载 ticket 和 URL 生成不因路径名被刻意隐藏,但仍必须按普通 read ACL、token、private、owner 规则鉴权。
29
+ 5. `group_data` 占用的空间必须计入真实 owner AID 的 Storage 配额。
30
+ 6. 隐藏和保护只改变可见性与入口,不改变数据归属、配额归属和审计归属。
31
+ 7. 成员数据写入只允许成员本人通过 `group.fs.*` 写自己的槽位子路径。
32
+ 8. `group.fs.*` 不允许删除 `memberdata` 根、成员槽位根或对应的 `group_data/{group_aid}` 根。
33
+
34
+ ## 16.4 `memberdata` 保护规则
35
+
36
+ `memberdata` 在 Group FS 视图中表现为虚拟目录和成员槽位边界。普通 Storage 面不因为路径名是 `memberdata` 而隐藏读、stat 或列表结果;但 group AID 命名空间下的 `memberdata/...` 不能被普通 Storage 写入口直接创建、修改、删除或替换。
37
+
38
+ ### 16.4.1 允许行为
39
+
40
+ | 操作 | 路径 | 结果 |
41
+ | --- | --- | --- |
42
+ | `stat/lstat` | `group_aid:/memberdata` | 返回虚拟目录节点 |
43
+ | `ls` | `group_aid:/memberdata` | 返回成员槽位虚拟节点列表 |
44
+ | `stat/lstat` | `group_aid:/memberdata/{member_ref}` | 返回成员槽位节点 |
45
+ | `ls/find/df` | `group_aid:/memberdata/{member_ref}` | 通过 group 服务映射到成员真实 `group_data/{group_aid}` |
46
+ | `mkdir/cp/mv/rm` | `group_aid:/memberdata/me/path` | 成员本人可操作自己的槽位子路径 |
47
+ | `cp` 下载 | `group_aid:/memberdata/{member_ref}/path` | 合法群成员按读权限下载 |
48
+
49
+ ### 16.4.2 拒绝行为
50
+
51
+ | 操作 | 路径 | 要求 |
52
+ | --- | --- | --- |
53
+ | `mkdir/rm/mv/cp` | `group_aid:/memberdata` | 必须拒绝 |
54
+ | `rm/mv/cp` 覆盖槽位 | `group_aid:/memberdata/{member_ref}` | 必须拒绝,不能删除或替换槽位根 |
55
+ | 写他人槽位 | `group_aid:/memberdata/{other}/path` | 必须拒绝 |
56
+ | 普通 Storage 写 group 空间 `memberdata/...` | `group_aid:/memberdata/...` | 必须拒绝,禁止绕过 group.fs;普通读/列表不因目录名隐藏 |
57
+ | 普通挂载到槽位子路径 | `memberdata/{aid}/subdir` | 必须拒绝,只允许精确槽位根挂载语义 |
58
+
59
+ `rm group_aid:/memberdata/{member_ref}` 不得解释为删除成员真实数据。若需要解除成员槽位挂载,应使用明确的 `group.fs.umount` 或等价控制面语义。
60
+
61
+ ## 16.5 `group_data` 保护规则
62
+
63
+ `group_data` 是成员个人 Storage 内的内部协议根,用于承载该成员在某群的成员数据。它不是普通应用目录。
64
+
65
+ ### 16.5.1 普通 Storage 面行为
66
+
67
+ 普通 `storage.*`、`storage.fs.*`、`aun fs` 和 Storage VFS 对 `group_data` 的处理分三类:
68
+
69
+ - 目录树浏览类入口必须隐藏:`storage.fs.list/find/stat/lstat/resolve/df`、`list_objects`、`list_prefixes`、`list_children`、`get_folder` 等在浏览 owner 目录结构时不得展示 `group_data` 根或其子树;直接指向 `group_data/...` 的树视图请求应返回 not found。
70
+ - 读/下载类入口不刻意隐藏:`get_object`、`head_object`、`get_object_url`、`create_download_ticket`、`check_access(read)` 不应仅因路径位于 `group_data/...` 而返回 not found;它们仍按普通 read ACL、token、private、owner 和群成员读代理规则鉴权。
71
+ - 写入和状态变更类入口必须拒绝:`put_object`、`append_object`、`set_object_meta`、`delete_object`、`check_upload`、`create_upload_session`、`complete_upload`、`mkdir`、`copy`、`move`、`rename`、`remove`、`delete`、`symlink`、`mount`、`set_acl`、`remove_acl`、`set_visibility`、`issue_token`、`revoke_token` 等作用于 `group_data` 或其子路径时必须拒绝,除非请求来自可信 `group.fs.*` 内部授权路径,或来自 `collab.*` 对 `.collab-versions` / `.collab-snapshots` 等协作内部对象的受控写入。
72
+
73
+ `df owner:/` 的总量必须包含 `group_data` 占用;`df owner:/group_data/...` 属于目录树 scoped 浏览,普通请求应返回 not found。
74
+
75
+ 上述隐藏和拒绝由服务端 storage RPC 强制实现;CLI、SDK VFS 和其他客户端只呈现服务端返回结果,不要求实现独立的系统目录识别或保护分支。
76
+
77
+ 对外错误建议:目录树隐藏返回 not found;写入和状态变更拒绝返回权限错误。调试模式或内部审计日志可以记录 reserved path 拒绝原因。
78
+
79
+ ### 16.5.2 Group FS 内部访问
80
+
81
+ 可信 `group.fs.*` 内部调用可以访问 `group_data/{group_aid}`:
82
+
83
+ - `_internal_caller_id == "group.fs"`。
84
+ - `_trusted_internal_caller_id == "group"`。
85
+ - `_group_fs_group_aid` 必须与 `group_data/{group_aid}` 根一致。
86
+ - `_group_fs_storage_owner_aid` 必须是成员 AID。
87
+ - `_group_fs_storage_bucket` 与当前 bucket 匹配。
88
+ - `_group_fs_storage_path` 必须覆盖当前真实路径 scope。
89
+ - 写操作要求 `_group_fs_actor_aid == _group_fs_storage_owner_aid`。
90
+ - 读操作要求 actor 是合法群成员,跨域读取必须通过 group 代理上下文校验。
91
+
92
+ group.fs 内部访问也不能删除 `group_data/{group_aid}` 根本身,只能操作根以下的业务子路径。
93
+
94
+ `collab.*` 只能在已解析的 `collab_root=group_aid:/memberdata/{member_aid}/...` 范围内写入协作内部对象;协作写授权通过 `collab.set_acl/remove_acl` 面向具体 AID 管理,不允许客户端直接调用 `storage.set_acl/remove_acl` 操作 `group_data`。
95
+
96
+ ## 16.6 配额与计费
97
+
98
+ `group_data` 内的所有对象、目录元数据和派生 blob 引用必须计入真实 owner AID 的 Storage 配额。
99
+
100
+ 规则如下:
101
+
102
+ 1. `member_aid:/group_data/{group_aid}/...` 的大小计入 `member_aid`,不计入 `group_aid`。
103
+ 2. group owner、admin 或其他成员通过 group.fs 读取成员数据,不改变配额归属。
104
+ 3. group.fs 上传到 `memberdata/me/...` 时,写前配额检查使用成员本人的 quota。
105
+ 4. `df group_aid:/memberdata/{member_ref}` 可以返回成员槽位视图,但其中 quota 字段必须明确表示真实 owner 是 `member_aid`。
106
+ 5. 普通 `aun fs df member_aid:/` 可以统计 `group_data` 占用,但默认不展示目录名;总量必须包含它。
107
+ 6. 群解散、成员退出或权限变化不会自动把 `group_data` 从配额中排除。
108
+
109
+ 这保证系统目录保护不会变成绕过个人存储限额的通道。
110
+
111
+ ## 16.7 生命周期与删除策略
112
+
113
+ | 场景 | 数据处理 |
114
+ | --- | --- |
115
+ | 成员退出或被踢出群 | 保留其个人 `group_data/{group_aid}` 数据;group.fs 不再允许群内其他成员访问 |
116
+ | 群解散 | 默认不删除成员个人 `group_data/{group_aid}` 数据 |
117
+ | 成员主动清理 | 必须通过明确的成员数据清理流程,不通过普通 Storage 路径暴露 `group_data` |
118
+ | 槽位卸载 | 只移除视图/挂载关系,不删除真实数据 |
119
+ | 管理员清理 | 必须有独立授权和审计,不复用普通文件删除语义 |
120
+
121
+ 如果未来提供“清理某群成员数据”能力,应使用语义化 API,例如 `group.fs.purge_member_data` 或用户侧隐私清理入口,并要求二次确认、审计记录和配额变更事件。
122
+
123
+ ## 16.8 CLI / SDK / RPC 要求
124
+
125
+ ### CLI
126
+
127
+ - `aun fs` 的列表、访问错误和拒绝结果由 `storage.fs.*` 服务端返回决定,不新增专门的 `group_data` 保护逻辑。
128
+ - `aun group fs` 的 `memberdata` 视图和根/槽位根破坏性操作拒绝由 `group.fs.*` 服务端返回决定。
129
+ - 错误消息按通用错误映射呈现,不鼓励用户拼接真实路径。
130
+
131
+ ### SDK VFS
132
+
133
+ - Storage VFS 不新增 `group_data` 特判,继续调用普通 `storage.fs.*`。
134
+ - GroupFSVFS 只传 `group_aid:/memberdata/{member_ref}/...` 视图路径并调用 `group.fs.*`。
135
+ - 四语言 SDK 均不得包含 `memberdata -> group_data` 的客户端映射逻辑,也不得把系统目录保护实现前移到客户端。
136
+
137
+ ### RPC
138
+
139
+ - 普通 `storage.*` / `storage.fs.*` 对 reserved root fail-closed。
140
+ - `group.fs.*` 是唯一可间接访问成员数据的公开 RPC 面。
141
+ - storage 内部只信任服务端注入的 group_fs context,不信任客户端提交的同名字段,跨域 relay 时必须保持可信来源校验。
142
+
143
+ ## 16.9 审计与可观测性
144
+
145
+ Storage 应记录以下内部审计事件:
146
+
147
+ - 普通目录树入口隐藏 `group_data`。
148
+ - 普通读/下载入口访问 `group_data` 按 read 权限鉴权,不因目录名隐藏。
149
+ - 普通写入和状态变更入口访问 `group_data` 被拒绝。
150
+ - 普通入口写 group 空间 `memberdata` 被拒绝。
151
+ - group.fs 代理读取成员槽位。
152
+ - group.fs 成员本人写入槽位子路径。
153
+ - 尝试删除 `memberdata` 根、槽位根或 `group_data/{group_aid}` 根。
154
+
155
+ 审计记录应包含 requester、actor、group_aid、storage_owner_aid、operation、view_path、storage_path、decision 和 reason。普通用户可见错误不必暴露真实 storage_path。
156
+
157
+ ## 16.10 测试验收
158
+
159
+ 必须覆盖以下测试:
160
+
161
+ - 普通 storage 写 `group_data/{group_aid}/a.txt` 被拒绝。
162
+ - 普通 storage owner 对 `group_data/{group_aid}/a.txt` 的 `get_object/head_object/create_download_ticket/check_access(read)` 按普通读权限成功。
163
+ - 普通 storage `mkdir/rm/mv/cp/symlink/mount` 涉及 `group_data` 被拒绝。
164
+ - 普通 `ls/find/stat/lstat/resolve/list_children/list_objects/list_prefixes` 不返回 `group_data` 项或对子路径返回 not found,但 `df /` 总量包含其占用。
165
+ - 普通 Storage 读/list/stat `memberdata/...` 不因目录名隐藏;普通写 `memberdata/...` 被拒绝。
166
+ - `group.fs.cp local -> group_aid:/memberdata/me/a.txt` 成功,配额扣在成员 AID。
167
+ - `group.fs.rm group_aid:/memberdata/me/a.txt` 成功。
168
+ - `group.fs.rm group_aid:/memberdata/me` 被拒绝或转为非删除真实数据的卸载语义。
169
+ - 成员不能写他人 `memberdata/{other}`。
170
+ - 非成员不能通过 group.fs 读写任意 `memberdata` 槽位。
171
+ - 群解散或成员退出后,普通 Storage 仍不暴露 `group_data`,group.fs 访问按成员关系 fail-closed。
172
+
173
+ ## 16.11 与相关协议的关系
174
+
175
+ - Group 子协议负责定义 `memberdata` 视图、成员槽位权限和 `group.fs.*` 控制面。
176
+ - Storage 子协议负责定义 `group_data` 真实根保护、配额统计、普通 storage 面的目录树隐藏、读/下载鉴权和写保护行为。
177
+ - SDK 文档只描述 `memberdata` 视图路径,不暴露真实根作为应用开发入口。
@@ -39,8 +39,9 @@ AUN 是 ACP 协议的 2.0 版本,采用 WebSocket + JSON-RPC 2.0 定义 Agent
39
39
  |------|------|
40
40
  | [06-服务协议.md](06-服务协议.md) | 业务层方法:message.* / meta.* / search.* / task.* / 跨域消息路由 / E2EE 摘要 / `pki.{issuer}` 与 `ct.{issuer}` 公开端点 |
41
41
  | [07-错误码与状态机.md](07-错误码与状态机.md) | 错误码分层汇总、各模式状态机、可重试/不可重试分类 |
42
- | [08-AUN-E2EE.md](08-AUN-E2EE.md) | 端到端加密安全层:密文格式、签名、防重放、prekey 管理(横跨三种模式) |
43
- | [08-AUN-E2EE-Group.md](08-AUN-E2EE-Group.md) | 群组 E2EE:Epoch Group Key、Membership Commitment、密钥分发与恢复 |
42
+ | [08-AUN-E2EE.md](08-AUN-E2EE.md) | Legacy P2P E2EE 信封说明;当前默认主路径见 SDK V2 多设备 wrap 文档 |
43
+ | [08-AUN-E2EE-Group.md](08-AUN-E2EE-Group.md) | 群组 E2EE V2:消息级密钥、逐设备密钥包裹、成员状态签名验证 |
44
+ | [16-系统目录保护方案.md](16-系统目录保护方案.md) | `memberdata` 与 `group_data` 的系统目录保护、`group_data` 目录树隐藏与读下载/写保护边界、Group FS 授权路径和配额归属 |
44
45
 
45
46
  ### 附录
46
47
 
@@ -57,7 +58,7 @@ AUN 是 ACP 协议的 2.0 版本,采用 WebSocket + JSON-RPC 2.0 定义 Agent
57
58
  | I | [附录I-跨域消息路由实现指南.md](附录I-跨域消息路由实现指南.md) | 跨域消息路由实现 |
58
59
  | J | [附录J-客户端接入示例.md](附录J-客户端接入示例.md) | 客户端接入示例 |
59
60
  | K | [附录K-Agent_Web发现协议.md](附录K-Agent_Web发现协议.md) | Agent Web 发现协议 |
60
- | L | [附录L-E2EE实现指南.md](附录L-E2EE实现指南.md) | E2EE 实现指南 |
61
+ | L | [附录L-E2EE实现指南.md](附录L-E2EE实现指南.md) | Legacy E2EE 实现指南 |
61
62
  | M | [附录M-JWT认证实现指南.md](附录M-JWT认证实现指南.md) | JWT 认证实现指南 |
62
63
 
63
64
  ## 快速导航
@@ -66,7 +67,7 @@ AUN 是 ACP 协议的 2.0 版本,采用 WebSocket + JSON-RPC 2.0 定义 Agent
66
67
 
67
68
  **协议实现者**:[02-证书体系](02-证书与信任体系.md) → [01-auth](01-身份与凭证协议-auth.md) → [04-Peer](04-Peer-子协议.md) → [06-服务协议](06-服务协议.md) → [07-错误码](07-错误码与状态机.md)
68
69
 
69
- **安全审计**:[02-证书体系](02-证书与信任体系.md) → [09-安全考虑](09-安全考虑.md) → [AUN-E2EE](08-AUN-E2EE.md)
70
+ **安全审计**:[02-证书体系](02-证书与信任体系.md) → [09-安全考虑](09-安全考虑.md) → [E2EE V2 时序](../sdk/E2EE_V2消息通信时序图.md) / [群组 E2EE V2](08-AUN-E2EE-Group.md);旧 P2P 信封再查 [AUN-E2EE Legacy](08-AUN-E2EE.md)
70
71
 
71
72
  **SDK 设计**:[00-总览](00-总览与分层.md) → [06-服务协议](06-服务协议.md) → [AUN-SDK-跨语言设计方案](../../AUN-SDK-跨语言设计方案.md)
72
73
 
@@ -21,7 +21,7 @@ AUN 协议采用**主协议 + 子协议**架构:
21
21
  业务层与公共基础
22
22
  ├── 06-服务协议.md ← message/meta/search/task + 跨域消息路由
23
23
  ├── 07-错误码与状态机.md ← 错误码汇总、状态机
24
- └── 08-AUN-E2EE.md ← E2EE 安全层(横跨三种模式)
24
+ └── 08-AUN-E2EE.md ← Legacy P2P E2EE 信封;当前主路径见 SDK E2EE V2 文档
25
25
  ```
26
26
 
27
27
  ## 渐进式查阅流程
@@ -43,7 +43,7 @@ AUN 协议采用**主协议 + 子协议**架构:
43
43
  | Relay 中继 | 05-Relay-子协议.md |
44
44
  | 消息收发、搜索、任务 | 06-服务协议.md |
45
45
  | 错误码和状态机 | 07-错误码与状态机.md |
46
- | E2EE 加密 | 08-AUN-E2EE.md |
46
+ | E2EE 加密 | ../sdk/E2EE_V2消息通信时序图.md / 08-AUN-E2EE-Group.md;旧信封查 08-AUN-E2EE.md |
47
47
  | 安全威胁和防护 | 09-安全考虑.md |
48
48
  | 客户端接入代码示例 | 附录J-客户端接入示例.md |
49
49
  | SDK 设计 | ../../AUN-SDK-跨语言设计方案.md |
@@ -16,13 +16,14 @@
16
16
  | 05 | [05-Relay-子协议.md](05-Relay-子协议.md) | `relay.*` 中继注册转发、透明封装、与 peer.* 关系 |
17
17
  | 06 | [06-服务协议.md](06-服务协议.md) | 业务层:message.* / meta.* / search.* / task.* / group.* + 跨域消息路由 |
18
18
  | 07 | [07-错误码与状态机.md](07-错误码与状态机.md) | 错误码汇总、各模式状态机、重试分类 |
19
- | E2EE | [08-AUN-E2EE.md](08-AUN-E2EE.md) | 端到端加密安全层(横跨三种模式) |
20
- | E2EE-Group | [08-AUN-E2EE-Group.md](08-AUN-E2EE-Group.md) | 群组 E2EE:Epoch Group Key、Membership Commitment、密钥恢复 |
19
+ | E2EE | [08-AUN-E2EE.md](08-AUN-E2EE.md) | Legacy P2P E2EE 信封说明;当前默认主路径见 SDK V2 多设备 wrap 文档 |
20
+ | E2EE-Group | [08-AUN-E2EE-Group.md](08-AUN-E2EE-Group.md) | 群组 E2EE V2:消息级密钥、逐设备密钥包裹、成员状态签名验证 |
21
21
  | 09 | [09-安全考虑.md](09-安全考虑.md) | 威胁模型、防护措施、升级安全、验签时序 |
22
22
  | 10 | [10-Group-子协议.md](10-Group-子协议.md) | `group.*` 群组管理、群消息、邀请码、资源共享、在线状态 |
23
23
  | 11 | [11-Storage-子协议.md](11-Storage-子协议.md) | `storage.*` 对象存储、大文件上传下载、预签名 URL |
24
24
  | 12 | [12-Stream-子协议.md](12-Stream-子协议.md) | `stream.*` 实时流式传输、WebSocket 推流、HTTP SSE 拉流、跨域拉流 |
25
25
  | 15 | [15-离线推送通知协议.md](15-离线推送通知协议.md) | `push.*` 离线推送、push_notify_aid 代理、事件通知 + 背压 ack、白名单与去重 |
26
+ | 16 | [16-系统目录保护方案.md](16-系统目录保护方案.md) | `memberdata` 与 `group_data` 的系统目录保护、目录树隐藏/读下载/写保护边界、配额归属和访问矩阵 |
26
27
 
27
28
  **附录**:A-术语表 | B-扩展性 | C-私钥管理 | D-Root CA 治理 | E-Root CA 准入 | F-Issuer CA 申请 | G-孤儿 AID | H-Auth 实现 | I-跨域消息路由 | J-客户端接入 | K-Agent Web | L-E2EE 实现 | M-JWT 实现
28
29
 
@@ -56,7 +57,8 @@
56
57
  | 群消息收发(group.send/pull) | 10 §10.5 |
57
58
  | 群成员权限(owner/admin/member) | 10 §10.2 |
58
59
  | 邀请码(group.create_invite_code) | 10 §10.7 |
59
- | 群文件系统(group.fs.*) | 10 §10.9 |
60
+ | 群文件系统(group.fs.*) | 10 §10.9 |
61
+ | 系统目录保护(memberdata / group_data) | 16 |
60
62
  | 对象存储(storage.*) | 11 |
61
63
  | 实时流传输(stream.*) | 12 |
62
64
  | 推流(WebSocket) | 12 §12.6 推流端点 |
@@ -97,22 +99,22 @@ Gateway 模式定位与职责、Gateway 发现机制、连接时序(auth.* →
97
99
  `relay.*` 3 个方法:register、forward、event/relay.message。Relay 职责边界(零信任笨管道)、透明封装规则、与 peer.* 配合完成端到端认证。
98
100
 
99
101
  ### 06-服务协议(业务层)
100
- 认证后可用的业务方法:auth.*(身份管理)、ca.*(证书管理)、message.*(P2P 消息、E2EE prekey、`payload.type` 负载类型)、meta.*(心跳、状态、受信根)、storage.*(文件存储)、group.*(群组)、mail.*(邮件)、stream.*(流式传输)、search.*(Agent 发现)、relay.*(中继)、peer.*(点对点)、task.*(协作任务)。同时列出 `pki.{issuer}` 与 `ct.{issuer}` 等公开 HTTP 端点入口。
102
+ 认证后可用的业务方法:auth.*(身份管理)、ca.*(证书管理)、message.*(P2P 消息、E2EE V2 设备密钥/bootstrap、`payload.type` 负载类型)、meta.*(心跳、状态、受信根)、storage.*(文件存储)、group.*(群组)、mail.*(邮件)、stream.*(流式传输)、search.*(Agent 发现)、relay.*(中继)、peer.*(点对点)、task.*(协作任务)。同时列出 `pki.{issuer}` 与 `ct.{issuer}` 等公开 HTTP 端点入口。
101
103
 
102
104
  ### 07-错误码与状态机
103
105
  错误码分层汇总(JSON-RPC 通用 + AUN 协议级 + Peer/Relay/Search/Task/升级扩展码)。三种连接模式状态机。任务状态机。可重试/不可重试分类。
104
106
 
105
107
  ### AUN-E2EE
106
- 独立安全层,横跨三种连接模式。定义客户端间 E2EE 加解密(prekey_ecdh_v2 四路 ECDH / long_term_key 两级降级)、prekey 管理、密文格式、AAD 防篡改、防重放保护。无需在线协商。
108
+ 独立安全层,横跨三种连接模式。当前 SDK 主路径为 E2EE V2 多设备 wrap:P2P 使用 `e2ee.p2p_encrypted`,Group 使用 `e2ee.group_encrypted`;正文一消息一密钥,按 recipient 设备生成 `3DH` / `1DH` wrap,并由接收端验证 `sender_signature`、AAD 和 recipient proof / digest。旧 `prekey_ecdh_v2` / `long_term_key` 文档仅作为历史兼容材料保留。
107
109
 
108
110
  ### AUN-E2EE-Group
109
- 群组端到端加密规范。Epoch Group Key 机制(group_secret + HKDF 派生)、Membership Commitment(成员列表 SHA-256 摘要)、密钥分发与恢复协议、CAS epoch 轮换、群组密文格式与 AAD、防重放与降级防护。
111
+ 群组端到端加密规范(V2,当前唯一在用版本)。每条消息使用独立随机密钥,接收方按设备分别持有密钥包裹(wrap),不依赖群级共享对称密钥。成员状态通过签名版本链(state_version/state_chain)记录,接收方可据此检测状态分叉或篡改。群组密文格式、AAD 防篡改、防重放保护。
110
112
 
111
113
  ### 09-安全考虑
112
114
  威胁模型、传输层安全、认证安全、JWT 信任模型分析、连接升级安全(降级攻击/假地址注入/信令重放)、公开 AP 同步安全、证书轮换验签时序。
113
115
 
114
116
  ### 10-Group-子协议
115
- `group.*` 命名空间完整协议规范。群组生命周期(create/suspend/close)、成员管理(add/kick/set_role/transfer_owner)、群消息(send/pull/ack、`payload.type` 负载类型)、入群申请与邀请码、群规则与公告、资源共享(put/get/request_add/review_add)、在线状态(go_online/heartbeat)、事件推送(group.created/changed/message_created)、错误码(-33001~-33009)。Group Service 作为独立 AID 持有者运行。
117
+ `group.*` 命名空间完整协议规范。群组生命周期(create/suspend/resume/dissolve)、成员管理(add/kick/set_role/transfer_owner)、群消息(send/pull/ack、`payload.type` 负载类型)、入群申请与邀请码、群规则与公告、资源共享(put/get/request_add/review_add)、在线状态(go_online/heartbeat)、事件推送(group.created/changed/message_created)、错误码(-33001~-33009)。Group Service 作为独立 AID 持有者运行。
116
118
 
117
119
  ### 11-Storage-子协议
118
120
  `storage.*` 命名空间完整协议规范。控制面与数据面分离(小对象内联 RPC,大对象预签名 URL HTTP 传输)、per-AID 隔离、对象键路径化、版本化 CAS 并发控制。方法:put_object / get_object / delete_object / list_objects / create_upload_session / create_download_ticket。
@@ -123,4 +125,7 @@ Gateway 模式定位与职责、Gateway 发现机制、连接时序(auth.* →
123
125
  ### 15-离线推送通知协议
124
126
  目标 AID 全部设备离线时的推送机制。push_notify_aid 作为普通客户端 AID 连接 Gateway,通过 `event/push.offline_message` 事件接收推送摘要(仅元数据,不含正文),处理后回 `push.ack` RPC 释放 in-flight 槽位(默认 max_in_flight=1 串行确认,30s 超时不重试)。聚合机制:同一 target_aid 60s 冷却期内合并为一条推送(unread_count++、senders 去重追加)。鉴权:push_token 由 push_notify_aid 自签自验,Gateway 仅透传不解析;push_notify_aid 必须在 Gateway 白名单内。跨域:推送由目标 AID 所属域的 Gateway 触发,push_notify_aid 必须与目标 AID 同域。
125
127
 
128
+ ### 16-系统目录保护方案
129
+ 定义 `memberdata` 与 `group_data` 的分层保护。`memberdata` 不是隐藏目录,但根和成员槽位根不可被普通文件操作破坏,group AID 命名空间下的普通 Storage 写入必须拒绝;`group_data` 是成员个人 Storage 内部真实根,Storage 服务端必须在目录树浏览中隐藏它,读/下载按普通 read 权限处理,写入、删除、重命名、挂载、授权和状态变更必须拒绝。文档同时规定 `group_data` 空间计入真实 owner AID 配额,group.fs 是可信授权写入路径,并给出访问矩阵、生命周期、审计和测试验收要求。
130
+
126
131
 
@@ -72,7 +72,7 @@ AUN 13 号《Agent 行为规范》确立了**接收方无响应义务**的自主
72
72
  | 值 | 含义 |
73
73
  |----|------|
74
74
  | `peer` | 仅拒绝来自该 AID 的点对点消息(message.*) |
75
- | `group` | 仅在某个群组上下文拒绝(需配合 `context_ref` 指向 group_id |
75
+ | `group` | 仅在某个群组上下文拒绝(需配合 `context_ref` 指向目标态 `group_aid`;旧 `group_id` 仅作兼容输入) |
76
76
  | `all` | 拒绝该 AID 的全部交互(message、group 邀请、mail 等) |
77
77
 
78
78
  未知 scope **应当**按 `all` 处理(保守解释)。
@@ -142,12 +142,12 @@ JWT Header 中的密钥标识,用于指出该 token 是由哪一把签名密
142
142
  客户端本次登录所使用的认证方法,例如 `aid`、`pairing_code`、`kite_token`、`oauth`。Gateway 会把该信息作为会话上下文的一部分向下游透传,用于审计、风控或差异化授权。
143
143
 
144
144
  ### E2EE (End-to-End Encryption)
145
- 端到端加密,消息在发送方客户端加密,在接收方客户端解密。Gateway 只能转发密文,无法解密消息内容。采用 prekey_ecdh_v2(优先,四路 ECDH)和 long_term_key(降级,双 DH + HKDF)两级策略,每条消息独立密钥,无需在线协商。发送方对每条加密消息附加 ECDSA 签名(sender_signature),接收方强制验签。
146
-
147
- **加密流程**:
148
- 1. 密钥协商:ECDH (P-256),通过 prekey 或长期公钥
149
- 2. 密钥派生:HKDF-SHA256
150
- 3. 对称加密:AES-256-GCM
145
+ 端到端加密,消息在发送方客户端加密,在接收方客户端解密。Gateway 只能转发密文,无法解密消息内容。当前 SDK 主路径为 E2EE V2 多设备 wrap:每条消息独立生成 `master_key`,按接收设备分别生成 `3DH` / `1DH` recipient wrap,并在信封中携带 `sender_signature`、AAD 与 recipient digest/proof。接收方必须验签、验 AAD、验 recipient proof / digest 后再解密。
146
+
147
+ **加密流程**:
148
+ 1. 发送方构造 V2 envelope,正文使用 AES-256-GCM 加密
149
+ 2. recipient wrap 使用 P-256 ECDH + HKDF-SHA256 派生 wrap key
150
+ 3. 接收方按自己的 recipient 行解 wrap,再用 `master_key` 解密正文
151
151
 
152
152
  ## A.5 协议与传输
153
153
 
@@ -247,14 +247,14 @@ Edwards 曲线数字签名算法,基于 Curve25519,用于证书签名。
247
247
  ### Payload
248
248
  消息负载,实际的消息内容。对协议层透明,可以是任意格式(JSON、文本、二进制等)。
249
249
 
250
- ### Prekey
251
- 接收方预先生成的临时 ECDH 密钥对。公钥(附身份签名)上传到服务端,私钥保存在本地。发送方获取后用于 ECDH 密钥协商。定期轮换,旧私钥保留 7 天。
250
+ ### Prekey
251
+ 接收方预先生成的 ECDH 密钥对。当前 E2EE V2 主路径使用设备 SPK:P2P 设备 SPK 通过 `message.v2.put_peer_pk` 注册,群内独立 group SPK 通过 `group.v2.put_group_pk` 注册,公钥由 AID 私钥签名背书,私钥仅保存在本地。旧 `message.e2ee.*` prekey 术语仅用于 legacy 信封兼容。
252
252
 
253
253
  ### Message ID
254
254
  消息标识符,全局唯一,用于消息去重、ACK 确认和防重放。
255
255
 
256
- ### Timestamp
257
- 时间戳,Unix 时间(秒),用于消息排序和时钟偏移检测。
256
+ ### Timestamp
257
+ 时间戳。消息、群事件、服务端 `timestamp` / `created_at` 等主路径字段使用 Unix 毫秒;少数签名辅助字段如 `spk_timestamp` 使用 Unix 秒时会在对应字段说明中单独标注。
258
258
 
259
259
  ## A.8 命名空间
260
260
 
@@ -264,7 +264,7 @@ JSON-RPC 方法的分组机制,使用点号分隔,例如 `auth.*`、`message
264
264
  **核心命名空间**:
265
265
  - `auth.*`:身份管理
266
266
  - `ca.*`:证书签发与管理
267
- - `message.*`:消息收发(含 E2EE prekey 管理 `message.e2ee.*`)
267
+ - `message.*`:消息收发,当前 E2EE V2 设备密钥路径包含 `message.v2.put_peer_pk` / `message.v2.bootstrap`
268
268
  - `meta.*`:元协议(ping、status 等)
269
269
 
270
270
  **扩展命名空间**:
@@ -304,8 +304,8 @@ Agent 的标准公开描述文档,对标 A2A 生态中的 Agent Card。AUN 中
304
304
  ### 刷新链 (Refresh Chain)
305
305
  通过 `auth.refresh_token` 连续刷新 JWT Token 形成的链条。推荐限制:总时长 ≤ 30 天,最大刷新次数 ≤ 720 次。
306
306
 
307
- ### 临时密钥对 (Ephemeral Keypair)
308
- E2EE 加密时生成的一次性 ECDH 密钥对,用于与接收方 prekey(或长期公钥)做密钥交换。每条消息使用独立的临时密钥对,用完即丢,提供前向保密性。
307
+ ### 临时密钥对 (Ephemeral Keypair)
308
+ E2EE V2 加密时生成的一次性 ECDH 密钥对,用于与接收方设备 IK/SPK 生成 recipient wrap。每条消息使用独立的临时密钥对,用完即丢;命中 SPK 时提供前向保密性,缺少 SPK 的 1DH 降级路径安全强度较低。
309
309
 
310
310
  ### 前向保密 (Forward Secrecy)
311
311
  即使长期密钥泄露,历史会话密钥也无法被破解的安全特性。通过使用临时密钥对实现。
@@ -1,11 +1,11 @@
1
- # 附录 L:E2EE 实现指南(非规范性)
2
-
3
- > **本文档为非规范性内容**:提供端到端加密的实现建议、交互流程、代码示例和安全考虑,不是协议强制要求。
4
- > 规范性定义见 [08-AUN-E2EE.md](08-AUN-E2EE.md)。
5
-
6
- ## L.0 加密模式概述
7
-
8
- AUN-E2EE 支持两种加密模式,SDK 实现应同时支持。
1
+ # 附录 L:E2EE Legacy 实现指南(非规范性)
2
+
3
+ > **本文档为非规范性内容**:提供端到端加密的实现建议、交互流程、代码示例和安全考虑,不是协议强制要求。
4
+ > 本文保留旧 `prekey_ecdh_v2` / `long_term_key` 实现说明,用于历史兼容和迁移排查。当前 SDK 默认使用 E2EE V2 多设备 wrap:P2P 为 `e2ee.p2p_encrypted`,Group 为 `e2ee.group_encrypted`,详见 `../sdk/E2EE_V2消息通信时序图.md` 和 [08-AUN-E2EE-Group.md](08-AUN-E2EE-Group.md)。
5
+
6
+ ## L.0 加密模式概述
7
+
8
+ 旧版 AUN-E2EE 支持两种加密模式。新实现不应把这两种旧信封作为默认发送格式。
9
9
 
10
10
  ### L.0.1 模式 1:prekey_ecdh_v2(优先)
11
11
 
@@ -264,6 +264,6 @@ AES-GCM + AAD 验证保证消息完整性。AAD 包含以下字段,按 Canonic
264
264
 
265
265
  ## L.7 兼容性说明
266
266
 
267
- - 发送端 **MUST** 使用 `prekey_ecdh_v2`(四路 ECDH)模式发送新消息
267
+ - 旧版发送端应优先使用 `prekey_ecdh_v2`(四路 ECDH)模式发送;当前新实现应使用 E2EE V2 多设备 wrap。
268
268
 
269
269
 
@@ -55,16 +55,17 @@ sequenceDiagram
55
55
  "protocol": { "min": "1.0", "max": "1.0" },
56
56
  "device": { "id": "来自 ~/.aun/.device_id", "type": "desktop" },
57
57
  "client": { "slot_id": "slot-a" },
58
- "delivery_mode": {
59
- "mode": "queue",
60
- "routing": "sender_affinity",
61
- "affinity_ttl_ms": 300000
62
- },
63
- "options": { "kind": "long" },
64
- "capabilities": {
65
- "e2ee": true,
66
- "group_e2ee": true
67
- }
58
+ "delivery_mode": {
59
+ "mode": "queue",
60
+ "routing": "sender_affinity",
61
+ "affinity_ttl_ms": 300000
62
+ },
63
+ "options": { "kind": "long" },
64
+ "extra_info": { "app": "demo" },
65
+ "capabilities": {
66
+ "e2ee": true,
67
+ "group_e2ee": true
68
+ }
68
69
  }
69
70
  }
70
71
  ```
@@ -74,10 +75,11 @@ sequenceDiagram
74
75
  - `protocol.min/max` 在 `auth.connect` 阶段完成 Gateway 会话版本协商;详细规则见协议文档 `03-Gateway-连接模式.md`。
75
76
  - `device.id` 是设备级稳定标识,Python SDK 默认从 `~/.aun/.device_id` 读取。
76
77
  - `client.slot_id` 由应用层显式传入,用于区分同设备上的多个实例槽位。SDK 允许 `/`、`:`、空格作为隔离键分隔符,例如 `evolclaw cli`、`evolclaw/cli`、`evolclaw:cli` 的隔离键都是 `evolclaw`。
77
- - `delivery_mode` 决定该 AID 当前连接的投递语义;同一 AID 的所有在线连接必须保持一致。
78
+ - `delivery_mode` 决定该 AID 当前连接的投递语义;同一 AID 的所有在线连接必须保持一致。
78
79
  - `options.kind` 声明连接类型:`"long"`(默认)= 长连接,承担服务端推送 / 事件订阅;`"short"` = 短连接,仅用于发送 RPC 并等待响应即断开。同 `(aid, device.id, slotIsolationKey(client.slot_id))` 隔离槽下,长连接最多 1 条,短连接最多 10 条;短连接不会顶掉长连接。
79
- - `options.short_ttl_ms` 仅在 `kind="short"` 时有效,可选;服务端兜底超时后主动关闭短连接,防止占名额。
80
- - `capabilities` 是客户端能力声明;`hello-ok.result.capabilities` 是服务端能力公告,不是双方能力交集。
80
+ - `options.short_ttl_ms` 仅在 `kind="short"` 时有效,可选;服务端兜底超时后主动关闭短连接,防止占名额。
81
+ - `extra_info` 是应用层自定义连接信息,可用于审计、踢人提示或排障;SDK 会过滤下划线开头的内部键。
82
+ - `capabilities` 是客户端能力声明;`hello-ok.result.capabilities` 是服务端能力公告,不是双方能力交集。
81
83
 
82
84
  ### (3) hello-ok — 握手完成
83
85
 
@@ -105,12 +105,15 @@ print(auth["access_token"], auth["gateway"])
105
105
  ### 连接
106
106
 
107
107
  ```python
108
- await client.connect({
109
- "slot_id": "main",
110
- "connection_kind": "long",
111
- "auto_reconnect": True,
112
- "heartbeat_interval": 30.0,
113
- "token_refresh_before": 60.0,
108
+ await client.connect({
109
+ "slot_id": "main",
110
+ "connection_kind": "long",
111
+ "delivery_mode": {"mode": "fanout"},
112
+ "background_sync": True,
113
+ "extra_info": {"app": "demo"},
114
+ "auto_reconnect": True,
115
+ "heartbeat_interval": 30.0,
116
+ "token_refresh_before": 60.0,
114
117
  "retry": {
115
118
  "initial_delay": 1.0,
116
119
  "max_delay": 64.0,
@@ -126,12 +129,14 @@ await client.connect({
126
129
  | 选项 | 说明 |
127
130
  |------|------|
128
131
  | `slot_id` | 同一设备内的实例槽位;允许 `/`、`:`、空格作为共享隔离键分隔符 |
129
- | `connection_kind` | `"long"` 或 `"short"` |
130
- | `short_ttl_ms` | 短连接服务端兜底超时 |
131
- | `delivery_mode` | 连接级投递语义 |
132
- | `auto_reconnect` | 断线后是否自动重连 |
133
- | `heartbeat_interval` | 心跳间隔,秒 |
134
- | `token_refresh_before` | token 过期前刷新提前量,秒 |
132
+ | `connection_kind` | `"long"` 或 `"short"` |
133
+ | `short_ttl_ms` | 短连接服务端兜底超时 |
134
+ | `delivery_mode` | 连接级投递语义 |
135
+ | `extra_info` | 应用层自定义连接信息;下划线开头的键不会透传给 Gateway |
136
+ | `background_sync` | 连接成功后是否执行 SDK 后台补洞 / 未读同步,默认开启 |
137
+ | `auto_reconnect` | 断线后是否自动重连 |
138
+ | `heartbeat_interval` | 心跳间隔,秒 |
139
+ | `token_refresh_before` | token 过期前刷新提前量,秒 |
135
140
  | `retry.initial_delay` / `retry.max_delay` | 退避重连参数 |
136
141
  | `timeouts.connect/call/http` | 连接、RPC、HTTP 超时 |
137
142
 
@@ -188,10 +193,11 @@ print(client.can_connect, client.can_send, client.is_online)
188
193
 
189
194
  | 事件 | 说明 |
190
195
  |------|------|
191
- | `state_change` | 状态变化,payload 中的 `state` 是九态公开值 |
192
- | `connection.error` | 连接、认证、重连错误 |
193
- | `token.refreshed` | token 自动刷新完成 |
194
- | `message.received` | 收到消息 |
196
+ | `state_change` | 状态变化,payload 中的 `state` 是九态公开值 |
197
+ | `connection.error` | 连接、认证、重连错误 |
198
+ | `token.refreshed` | token 自动刷新完成 |
199
+ | `token.refresh_exhausted` | refresh_token 缺失、过期或刷新链耗尽,SDK 已清理本地 token,下一次重连会重新走完整登录 |
200
+ | `message.received` | 收到消息 |
195
201
  | `group.changed` | 群组事件 |
196
202
  | `message.undecryptable` / `group.message_undecryptable` | E2EE 解密失败 |
197
203
 
@@ -238,8 +244,10 @@ state = await store.check_agent_md("bob.agentid.pub", ttl_days=1)
238
244
  | `AUNClient` | 连接、事件和 RPC 调用;不再暴露 agent.md 上传入口 |
239
245
 
240
246
  本地落盘位置由 SDK 管理。Python / TypeScript / Go 写入 `{aun_path}/AIDs/{aid}/agent.md` 和同目录 `agentmd.json`;浏览器 JavaScript 写入 IndexedDB 的等价 logical key,存储不可用时退化为内存缓存。agent.md 不写入 SQLite,也不再使用旧 `{aun_path}/AgentMDs` 目录。
241
-
242
- ---
247
+
248
+ 连接后的 RPC 响应、事件推送和消息信封会被 SDK 自动观察:Gateway `_meta.agent_md_etags` 中的 `requester`、`peer`、`group` 以及兼容别名 `receiver`、`target`、`to`、`sender`、`from` 会更新对应 AID 的 `remote_etag` / `last_modified`;V2 信封中的 `agent_md.sender` 和 `agent_md.group` 也会写入同一份本地记录。`group` 表示群自身 `group_aid` / `group_id` 的 agent.md,缺少 `aid` 时 SDK 会从信封顶层或 AAD 的 `group_aid` / `group_id` 兜底。
249
+
250
+ ---
243
251
 
244
252
  ## RPC 调用
245
253