@agentunion/fastaun-browser 0.5.16 → 0.5.18

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 (83) hide show
  1. package/CHANGELOG.md +334 -258
  2. package/_packed_docs/CHANGELOG.md +334 -258
  3. package/_packed_docs/INDEX.md +36 -5
  4. package/_packed_docs/KITE_DOCS_GUIDE.md +13 -5
  5. package/_packed_docs/agent.md/SCHEMA.md +52 -33
  6. package/_packed_docs/aun/345/210/206/345/270/203/345/274/217/346/265/213/350/257/225/350/277/220/350/241/214/346/214/207/345/215/227.md +1170 -1164
  7. package/_packed_docs/aun/346/265/213/350/257/225/350/277/220/350/241/214/346/214/207/345/215/227.md +1215 -1213
  8. 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 +95 -6
  9. package/_packed_docs/protocol/06-/346/234/215/345/212/241/345/215/217/350/256/256.md +58 -43
  10. 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 +19 -4
  11. package/_packed_docs/protocol/10-Group-/345/255/220/345/215/217/350/256/256.md +80 -17
  12. package/_packed_docs/protocol/11-Storage-/345/255/220/345/215/217/350/256/256.md +25 -2
  13. package/_packed_docs/sdk/06-API/346/211/213/345/206/214.md +69 -10
  14. package/_packed_docs/sdk/07-/351/224/231/350/257/257/345/244/204/347/220/206.md +7 -4
  15. package/_packed_docs/sdk/09-group-rpc-manual.md +167 -35
  16. package/_packed_docs/sdk/09-message-rpc-manual.md +72 -42
  17. package/_packed_docs/sdk/09-storage-rpc-manual.md +48 -18
  18. package/_packed_docs/sdk/AUN_DOCS_GUIDE.md +16 -12
  19. package/_packed_docs/sdk/INDEX.md +14 -13
  20. package/dist/agent-md-schema.d.ts.map +1 -1
  21. package/dist/agent-md-schema.js +2 -0
  22. package/dist/agent-md-schema.js.map +1 -1
  23. package/dist/agent-md.d.ts +3 -1
  24. package/dist/agent-md.d.ts.map +1 -1
  25. package/dist/agent-md.js +13 -4
  26. package/dist/agent-md.js.map +1 -1
  27. package/dist/aid-store.d.ts +45 -0
  28. package/dist/aid-store.d.ts.map +1 -1
  29. package/dist/aid-store.js +231 -3
  30. package/dist/aid-store.js.map +1 -1
  31. package/dist/aid.d.ts +17 -1
  32. package/dist/aid.d.ts.map +1 -1
  33. package/dist/aid.js +49 -2
  34. package/dist/aid.js.map +1 -1
  35. package/dist/bundle.js +2763 -1591
  36. package/dist/cert-utils.d.ts.map +1 -1
  37. package/dist/cert-utils.js +5 -3
  38. package/dist/cert-utils.js.map +1 -1
  39. package/dist/client/delivery.d.ts +19 -0
  40. package/dist/client/delivery.d.ts.map +1 -1
  41. package/dist/client/delivery.js +198 -12
  42. package/dist/client/delivery.js.map +1 -1
  43. package/dist/client/group-state.d.ts +4 -0
  44. package/dist/client/group-state.d.ts.map +1 -1
  45. package/dist/client/group-state.js +63 -0
  46. package/dist/client/group-state.js.map +1 -1
  47. package/dist/client/rpc-pipeline.d.ts.map +1 -1
  48. package/dist/client/rpc-pipeline.js +46 -5
  49. package/dist/client/rpc-pipeline.js.map +1 -1
  50. package/dist/client/v2-e2ee.d.ts +7 -1
  51. package/dist/client/v2-e2ee.d.ts.map +1 -1
  52. package/dist/client/v2-e2ee.js +918 -463
  53. package/dist/client/v2-e2ee.js.map +1 -1
  54. package/dist/client.d.ts.map +1 -1
  55. package/dist/client.js +73 -14
  56. package/dist/client.js.map +1 -1
  57. package/dist/facades.d.ts +7 -0
  58. package/dist/facades.d.ts.map +1 -1
  59. package/dist/facades.js +21 -0
  60. package/dist/facades.js.map +1 -1
  61. package/dist/group-fs.d.ts.map +1 -1
  62. package/dist/group-fs.js +8 -5
  63. package/dist/group-fs.js.map +1 -1
  64. package/dist/index.d.ts +3 -2
  65. package/dist/index.d.ts.map +1 -1
  66. package/dist/index.js +1 -0
  67. package/dist/index.js.map +1 -1
  68. package/dist/ownership-proof.d.ts +30 -0
  69. package/dist/ownership-proof.d.ts.map +1 -0
  70. package/dist/ownership-proof.js +97 -0
  71. package/dist/ownership-proof.js.map +1 -0
  72. package/dist/storage/vfs.d.ts +1 -0
  73. package/dist/storage/vfs.d.ts.map +1 -1
  74. package/dist/storage/vfs.js +68 -5
  75. package/dist/storage/vfs.js.map +1 -1
  76. package/dist/tools/cross-sdk-agent.js +34 -3
  77. package/dist/tools/cross-sdk-agent.js.map +1 -1
  78. package/dist/transport.js +34 -34
  79. package/dist/types.d.ts +16 -1
  80. package/dist/types.d.ts.map +1 -1
  81. package/dist/version.d.ts +1 -1
  82. package/dist/version.js +1 -1
  83. package/package.json +13 -13
@@ -92,11 +92,98 @@ AID 命名规则:
92
92
  }
93
93
  ```
94
94
 
95
- **说明**:
96
- - Gateway 将请求转发到 Auth 服务,Auth 服务调用 CA 签发证书
97
- - 创建 AID 时固定签发 P-256 证书,确保最大兼容性
98
- - 协议默认允许创建任意 `aid`;命名冲突、抢注、保留名、审批制等约束由具体网络运营策略决定
99
- - 客户端需保存返回的证书和本地生成的私钥
95
+ **说明**:
96
+ - Gateway 将请求转发到 Auth 服务,Auth 服务调用 CA 签发证书
97
+ - 创建 AID 时固定签发 P-256 证书,确保最大兼容性
98
+ - 协议默认允许创建任意 `aid`;命名冲突、抢注、保留名、审批制等约束由具体网络运营策略决定
99
+ - 客户端需保存返回的证书和本地生成的私钥
100
+
101
+ ### 1.3.1 带 type/owner 的新注册流程
102
+
103
+ `auth.create_aid` 只负责签发证书,保持 legacy 兼容语义,不创建 owner relation。支持 owner 的新身份由 SDK 先完成证书签发,再调用以下可恢复 operation:
104
+
105
+ ```text
106
+ 证书签发(auth.create_aid)
107
+ → auth.aid_register_prepare
108
+ → auth.aid_register_submit(subject/owner 签名,可分批)
109
+ → 使用 owner_operation_id 发布带 ownership_proof 的 agent.md
110
+ → auth.aid_register_activate
111
+ ```
112
+
113
+ #### auth.aid_register_prepare
114
+
115
+ | 参数 | 类型 | 必需 | 说明 |
116
+ |------|------|:----:|------|
117
+ | `aid`(或 `subject_aid`) | string | 是 | subject AID;服务端规范化为小写 |
118
+ | `type`(或 `aid_type`) | string | 是 | `human`、`agent`、`group`、`service`、`device`、`host`、`org`、`custom` |
119
+ | `owner`(或 `owner_aid`) | string | 条件 | 非 `human` 必填;`agent` 可与 subject 相同 |
120
+ | `idempotency_key` | string | 否 | 相同 kind/subject/key 返回同一 operation |
121
+
122
+ 约束:`human` 不得指定 owner;非 `human` 必须指定 owner;只有 `agent` 允许 self-owner;外部 owner 必须是已登记且状态为 `active` 或 `not_applicable` 的 `human`/`agent`,并且不能形成 owner 环。prepare 成功后 operation 的初始 state 为 `proof_pending`(无 owner 的 human 为 `agent_md_pending`),TTL 固定为 7 天。
123
+
124
+ Auth 可登记 `org` 关系类型;但当前 CA/Name Service 只实现 `signing` 与 `group_identity` 证书用途,尚未实现 `org_identity` 映射。组织身份若使用现有流程,不能按已实现的组织专用证书用途对外承诺。
125
+
126
+ **响应**(字段会按场景返回):
127
+
128
+ ```json
129
+ {
130
+ "operation_id": "op-...",
131
+ "kind": "register",
132
+ "aid": "sensor.agentid.pub",
133
+ "subject_aid": "sensor.agentid.pub",
134
+ "type": "agent",
135
+ "owner": "alice.agentid.pub",
136
+ "owner_aid": "alice.agentid.pub",
137
+ "state": "proof_pending",
138
+ "operation_state": "proof_pending",
139
+ "ownership_status": "pending",
140
+ "relation_version": 0,
141
+ "proof_id": "550e8400-e29b-41d4-a716-446655440000",
142
+ "fact_hash": "<64 lowercase hex>",
143
+ "statement_hash": "<64 lowercase hex>",
144
+ "expires_at": "2026-10-13T00:00:00Z"
145
+ }
146
+ ```
147
+
148
+ #### auth.aid_register_submit
149
+
150
+ 请求至少包含 `operation_id`,并可分批提交:
151
+
152
+ | 参数 | 类型 | 说明 |
153
+ |------|------|------|
154
+ | `subject_signature` | object | subject 对 ownership statement 的签名 |
155
+ | `owner_signature` | object | 外部 owner 对同一 statement 的签名;self-owner 禁止 |
156
+
157
+ 签名封套只允许 `cert_fingerprint`(`sha256:<64 hex>`)和严格 Base64 的 `signature`。提交后双方签名齐全时 state 变为 `agent_md_pending`;重复提交相同签名幂等,替换已保存签名返回 `owner_relation_conflict`。
158
+
159
+ #### auth.aid_register_activate / auth.aid_register_status
160
+
161
+ `auth.aid_register_activate` 只接受 `operation_id`。客户端必须先用该 operation 的一次性 `owner_operation_id` 发布与 operation 完全匹配的 `agent.md`,成功后返回 `ownership_status=active`(`human` 返回 `not_applicable`)和 `relation_version=1`。`auth.aid_register_status` 接受 `aid`,返回当前登记或 pending operation 的状态。
162
+
163
+ ### 1.3.2 已有 AID 的 aid_bind 流程
164
+
165
+ 旧客户端通过 `auth.create_aid` 创建的 AID,以及已被 `owner_relation_unbind` 解除关系的 AID,使用 `auth.aid_bind_prepare`、`auth.aid_bind_submit`、`auth.aid_bind_activate` 和 `auth.aid_bind_status` 建立或重建关系。该流程不签发新证书、不改变 AID、密钥、登录或消息通信身份;绑定期间状态为 `legacy_unbound`/`pending`,基本登录和通信仍可用。
166
+
167
+ `aid_bind_prepare` 的参数和签名规则与新注册相同,但 active relation 不能被 bind 替换;已存在的 type/owner 只能重复提交完全相同的值。绑定失败或 operation 过期不会吊销证书。`auth.aid_operation_get` 接受 `operation_id`,用于进程重启后查询并恢复 pending operation。
168
+
169
+ ### 1.3.3 Ownership proof 与 canonical bytes
170
+
171
+ 四端实现必须对同一 UTF-8 字节序列计算摘要和签名:
172
+
173
+ ```text
174
+ fact = canonical_json({"subject_aid": subject_aid, "owner_aid": owner_aid})
175
+ statement = canonical_json({"proof_id": proof_id, "subject_aid": subject_aid, "owner_aid": owner_aid})
176
+ signing_bytes = UTF-8("AUN-AID-OWNER-RELATION-V1;") || statement
177
+ ```
178
+
179
+ 对象键按字典序、无空格;AID 先规范化为 ASCII 小写;`proof_id` 必须为 UUID v4。`fact_hash=SHA-256(fact)`,`statement_hash=SHA-256(signing_bytes)`,均为裸小写十六进制。agent.md 的 `owner` 与 `ownership_proof` 必须同时出现;proof 的 `subject_aid`/`owner_aid` 必须分别等于 agent.md 的 `aid`/`owner`。`human` 不得携带这两个字段。
180
+
181
+ ### 1.3.4 Owner change、解绑与 type 变更
182
+
183
+ - `auth.owner_change_prepare` 参数为 `subject_aid`、`new_owner_aid`、可选 `current_owner_aid`、`expected_relation_version`、`idempotency_key`;只允许当前 owner 发起,并检查 CAS、owner 类型和环。operation 的 `transfer_payload` 包含 `operation_id`、subject、old/new owner、new proof、当前 relation version、challenge nonce 和过期时间。
184
+ - `auth.owner_change_submit` 接收 `old_owner_signature`、`subject_signature`、`new_owner_signature`。old owner 签署 `AUN-AID-OWNER-TRANSFER-V1;` 加 `transfer_payload`;subject 和 new owner 签署新的 ownership statement。三份签名齐全后发布新 agent.md,再调用 `auth.owner_change_activate`。
185
+ - 激活成功后 `relation_version` 递增;旧 owner 的 relation ACL 被撤销但数据保留,新 owner 的 ACL 被创建。subject 自身签名不能替代 old owner 授权。
186
+ - `auth.owner_relation_status` 查询当前关系;`auth.owner_relation_unbind` 只允许当前 owner(可带 `expected_relation_version`),状态变为 `unbound`,版本递增,证书和数据保留;`auth.aid_type_change` 修改登记 type,但有 active 子关系时拒绝。
100
187
 
101
188
  ## 1.4 auth.aid_login1 / auth.aid_login2
102
189
 
@@ -559,7 +646,9 @@ signature = ECDSA_sign(private_key, SHA256(message))
559
646
  | `-32003` | Signature verification failed — 签名验证失败 |
560
647
  | `-32005` | Authentication expired — Token 过期或刷新链耗尽 |
561
648
 
562
- > 通用 JSON-RPC 2.0 错误码(-32700/-32600/-32601/-32602/-32603)同样适用,见 [07-JSON-RPC](07-JSON-RPC.md)。
649
+ > 通用 JSON-RPC 2.0 错误码(-32700/-32600/-32601/-32602/-32603)同样适用,见 [07-JSON-RPC](07-JSON-RPC.md)。
650
+
651
+ Owner relation 方法使用 JSON-RPC `-32602`,并在 `error.data.error_code` 中返回稳定错误码;完整列表和 `signature_verification_unavailable`、`type_change_blocked`、`aid_binding_required` 的说明见 [07-错误码与状态机](07-错误码与状态机.md) §7.1。
563
652
 
564
653
  ## 1.9 安全说明
565
654
 
@@ -261,11 +261,12 @@ proxy-server 处理 `https://proxy.{issuer}/{user_name}/{svc_name}/...` 或等
261
261
  | `queue` | 单实例实时消费 | 内存环形缓冲 | 有限时间窗口(默认 5 分钟)+ 有限条数(默认 200 条/AID) | Worker/执行器消费、同一发送者尽量命中同一实例 |
262
262
  | `fanout` | 广播到在线实例 | 数据库 + 文件存储 | TTL 过期前持久保存(默认 24 小时) | 离线送达、历史查询、多实例同步接收 |
263
263
 
264
- **序列号机制**:
265
-
266
- - 每条消息(无论临时或持久化)在收件人维度分配一个递增 `seq`
267
- - 客户端通过 `after_seq` 游标增量拉取,支持多设备各自维护进度
268
- - `message.pull` 合并返回临时消息和持久化消息,按 `seq` 排序
264
+ **序列号机制**:
265
+
266
+ - `ttl <= 0` 的现有消息在收件人维度分配递增 `seq`
267
+ - `ttl > 0` 的 volatile 消息不分配持久 `seq`,使用独立 opaque `volatile_cursor`
268
+ - 客户端通过 `after_seq` 游标增量拉取,支持多设备各自维护进度
269
+ - `message.pull` 分别读取持久流与 volatile 流,并按服务端创建时间稳定合并
269
270
 
270
271
  #### `message.send`
271
272
 
@@ -277,9 +278,11 @@ proxy-server 处理 `https://proxy.{issuer}/{user_name}/{svc_name}/...` 或等
277
278
  "jsonrpc": "2.0",
278
279
  "id": 10,
279
280
  "method": "message.send",
280
- "params": {
281
- "to": "bob.aid.pub",
282
- "payload": {"type": "text", "text": "你好"}
281
+ "params": {
282
+ "to": "bob.aid.pub",
283
+ "device_id": "bob-phone",
284
+ "ttl": 300,
285
+ "payload": {"type": "text", "text": "你好"}
283
286
  }
284
287
  }
285
288
  ```
@@ -288,8 +291,11 @@ proxy-server 处理 `https://proxy.{issuer}/{user_name}/{svc_name}/...` 或等
288
291
 
289
292
  | 参数 | 必需 | 说明 |
290
293
  |------|:----:|------|
291
- | `to` | ✅ | 接收者 AID |
292
- | `payload` | ✅ | 消息载荷,对协议层透明,由应用层定义 |
294
+ | `to` | ✅ | 接收者 AID |
295
+ | `device_id` | ❌ | 目标接收设备;指定后只投递该设备,不会降级为 AID 全设备投递 |
296
+ | `to_device_id` | ❌ | `device_id` 的兼容别名 |
297
+ | `ttl` | ❌ | 秒;缺省或 `<=0` 持久化,正数钳制到 1–3600 秒并进入 volatile 内存通道 |
298
+ | `payload` | ✅ | 消息载荷,对协议层透明,由应用层定义 |
293
299
  | `type` | ❌ | 信封/封装类型,普通业务消息无需填写;SDK 加密发送时自动使用 `e2ee.encrypted` |
294
300
  | `encrypted` | ❌ | E2EE 标记(默认 `false`) |
295
301
  | `message_id` | ❌ | 幂等键(客户端提供或服务端生成 UUID) |
@@ -307,8 +313,10 @@ proxy-server 处理 `https://proxy.{issuer}/{user_name}/{svc_name}/...` 或等
307
313
  "status": "sent",
308
314
  "delivery_mode": "queue"
309
315
  }
310
- }
311
- ```
316
+ }
317
+ ```
318
+
319
+ 正 TTL 消息不写数据库或 WAL、不分配持久 `seq`,响应包含 `storage="volatile"`、`volatile_cursor`(多设备时可含 `volatile_cursors`)、`created_at`、`expires_at` 和 `status="accepted"`。`delivery_mode` 继续控制在线投递方式,不改变 TTL 存储语义。跨域只传递剩余 TTL,目标域不得重新应用 1 秒下限。
312
320
 
313
321
  ##### Payload 参考约定
314
322
 
@@ -360,7 +368,7 @@ proxy-server 处理 `https://proxy.{issuer}/{user_name}/{svc_name}/...` 或等
360
368
 
361
369
  #### `message.pull`
362
370
 
363
- 按游标拉取新消息。合并返回临时消息和持久化消息,按 `seq` 排序。
371
+ 按两个独立游标拉取持久消息和 volatile 消息。volatile 消息不进入持久 `seq` 空间。
364
372
 
365
373
  **请求**:
366
374
  ```json
@@ -368,11 +376,11 @@ proxy-server 处理 `https://proxy.{issuer}/{user_name}/{svc_name}/...` 或等
368
376
  "jsonrpc": "2.0",
369
377
  "id": 11,
370
378
  "method": "message.pull",
371
- "params": {
372
- "after_seq": 0,
379
+ "params": {
380
+ "after_seq": 0,
381
+ "after_volatile_cursor": "v1:i1:7:20",
373
382
  "limit": 50,
374
- "device_id": "device-001",
375
- "slot_id": "slot-a"
383
+ "device_id": "device-001"
376
384
  }
377
385
  }
378
386
  ```
@@ -381,10 +389,10 @@ proxy-server 处理 `https://proxy.{issuer}/{user_name}/{svc_name}/...` 或等
381
389
 
382
390
  | 参数 | 必需 | 说明 |
383
391
  |------|:----:|------|
384
- | `after_seq` | ❌ | 起始序列号(默认 0),返回 `seq > after_seq` 的消息 |
392
+ | `after_seq` | ❌ | 起始序列号(默认 0),返回 `seq > after_seq` 的消息 |
393
+ | `after_volatile_cursor` | ❌ | opaque volatile 游标;四个 SDK 自动维护,应用通常无需传入 |
385
394
  | `limit` | ❌ | 单次返回上限(默认 50,最大 50) |
386
395
  | `device_id` | ❌ | 多实例消费上下文中的设备标识;缺省时使用连接认证上下文 |
387
- | `slot_id` | ❌ | 同一设备下的消费槽位;空字符串表示设备单实例模式 |
388
396
  | `window_mode` | ❌ | 可选 Pull 模式;`tail` 表示读取以安全 Head 结尾的最新一页 |
389
397
 
390
398
  **响应**:
@@ -416,13 +424,17 @@ proxy-server 处理 `https://proxy.{issuer}/{user_name}/{svc_name}/...` 或等
416
424
  |------|------|------|
417
425
  | `messages` | array | 消息列表(临时 + 持久化合并,按 `seq` 排序) |
418
426
  | `count` | integer | 本次返回的消息条数 |
419
- | `latest_seq` | integer | 本次返回的最大 `seq` |
427
+ | `latest_seq` | integer | 本次返回的最大 `seq` |
428
+ | `latest_volatile_cursor` | string\|null | 本页最后一个 volatile 游标;不改变 `latest_seq` |
429
+ | `volatile_has_more` | boolean | 是否仍有未返回的 volatile 消息;SDK 在 volatile 游标前进时据此继续分页 |
430
+ | `volatile_earliest_cursor` | string\|null | 当前 boot epoch 内仍可读取的最早 volatile 游标 |
431
+ | `volatile_dropped_count` | integer | 当前 boot epoch 内因过期或容量淘汰而不可读的累计数 |
420
432
  | `ephemeral_earliest_available_seq` | integer\|null | 当前临时缓冲中最早可用的 `seq`,`null` 表示无临时消息 |
421
433
  | `ephemeral_dropped_count` | integer | 因缓冲淘汰而丢弃的临时消息计数 |
422
434
 
423
435
  > 客户端可通过 `ephemeral_earliest_available_seq` 判断是否有临时消息丢失:若 `after_seq < ephemeral_earliest_available_seq`,说明存在已被淘汰的消息。
424
436
 
425
- **说明**:不修改消息状态,多设备安全(各 `(aid, device_id, slot_id)` 维护各自的 `after_seq`),同一 `after_seq` 多次调用返回相同结果(幂等)。显式传入的 `device_id` / `slot_id` 若与连接认证上下文不一致,服务端 **MUST** 拒绝请求。
437
+ **说明**:持久游标与 volatile 游标独立推进。SDK 只把含正 `seq` 的消息送入持久 tracker;volatile push/pull 按发送方和 `message_id` 去重,交付成功后自动 ACK。SDK 在传输层注入内部 slot,应用不得传入或读取,任何消息、响应和事件都不得包含该字段。epoch 不匹配时 SDK 清空 volatile 游标并重试一次。`message.history` 不返回 volatile 消息。
426
438
 
427
439
  **Tail 模式**:`window_mode="tail"` 时,服务端固定安全 `head_seq`,返回跨度不超过 `limit` 的最新 seq band,并额外返回:
428
440
 
@@ -463,18 +475,18 @@ History 不触发实时消息事件。客户端解密 History 结果时不得修
463
475
 
464
476
  #### `message.ack`
465
477
 
466
- 确认已收到消息,推进服务端 ack 游标。
478
+ 确认已收到消息。持久 ACK 与 volatile ACK 可以单独提交,也可以在同一请求中提交。
467
479
 
468
480
  **请求**:
469
481
  ```json
470
482
  {
471
483
  "jsonrpc": "2.0",
472
484
  "id": 12,
473
- "method": "message.ack",
474
- "params": {
475
- "seq": 43,
476
- "device_id": "device-001",
477
- "slot_id": "slot-a"
485
+ "method": "message.ack",
486
+ "params": {
487
+ "seq": 43,
488
+ "volatile_cursors": ["v1:i1:7:21"],
489
+ "device_id": "device-001"
478
490
  }
479
491
  }
480
492
  ```
@@ -483,9 +495,11 @@ History 不触发实时消息事件。客户端解密 History 结果时不得修
483
495
 
484
496
  | 参数 | 必需 | 说明 |
485
497
  |------|:----:|------|
486
- | `seq` | ✅ | 确认到的序列号(含),表示该 seq 及之前的所有消息已收到 |
487
- | `device_id` | ❌ | 多实例消费上下文中的设备标识;缺省时使用连接认证上下文 |
488
- | `slot_id` | ❌ | 同一设备下的消费槽位;空字符串表示设备单实例模式 |
498
+ | `seq` | ❌ | 确认到的持久序列号(含);未提交 volatile ACK 时必填 |
499
+ | `volatile_cursor` | ❌ | 单个 volatile 游标的兼容形式 |
500
+ | `volatile_cursors` | ❌ | 要确认的 volatile 游标数组 |
501
+ | `volatile_ids` | ❌ | 要按 `message_id` 确认的 volatile 消息数组 |
502
+ | `device_id` | ❌ | 多实例消费上下文中的设备标识;缺省时使用连接认证上下文 |
489
503
 
490
504
  **响应**:
491
505
  ```json
@@ -496,7 +510,7 @@ History 不触发实时消息事件。客户端解密 History 结果时不得修
496
510
  }
497
511
  ```
498
512
 
499
- **说明**:`ack_seq` 仅增不减。现代连接按 `(aid, device_id, slot_id)` 维护 ack 游标;未携带 `device_id` 的 legacy 连接继续走 per-AID 兼容路径。显式传入的 `device_id` / `slot_id` 若与连接认证上下文不一致,服务端 **MUST** 拒绝请求。
513
+ **说明**:`ack_seq` 仅增不减;volatile 结果通过 `volatile_ack` 返回 `accepted`、`expired` 等幂等计数。服务端内部按消费 slot 隔离 lease,但 slot 不属于对外协议对象。
500
514
 
501
515
  #### `message.recall`
502
516
 
@@ -589,8 +603,9 @@ History 不触发实时消息事件。客户端解密 History 结果时不得修
589
603
  {
590
604
  "jsonrpc": "2.0",
591
605
  "method": "event/message.received",
592
- "params": {
593
- "from": "bob.aid.pub",
606
+ "params": {
607
+ "from": "bob.aid.pub",
608
+ "sender_device_id": "bob-phone",
594
609
  "to": "alice.aid.pub",
595
610
  "message_id": "550e8400-...",
596
611
  "seq": 42,
@@ -599,8 +614,10 @@ History 不触发实时消息事件。客户端解密 History 结果时不得修
599
614
  "delivery_mode": "queue",
600
615
  "encrypted": false
601
616
  }
602
- }
603
- ```
617
+ }
618
+ ```
619
+
620
+ volatile 事件包含 `storage="volatile"`、`volatile_cursor`、`created_at`、`expires_at`,不含持久 `seq` 或内部 slot。`sender_device_id` 始终表示发送方设备,可用于下一次定向发送。
604
621
 
605
622
  #### `event/message.ack`
606
623
 
@@ -611,19 +628,17 @@ History 不触发实时消息事件。客户端解密 History 结果时不得修
611
628
  "jsonrpc": "2.0",
612
629
  "method": "event/message.ack",
613
630
  "params": {
614
- "to": "bob.aid.pub",
615
- "device_id": "device-001",
616
- "slot_id": "slot-a",
617
- "ack_seq": 43,
631
+ "to": "bob.aid.pub",
632
+ "device_id": "device-001",
633
+ "ack_seq": 43,
618
634
  "timestamp": 1709712003
619
635
  }
620
636
  }
621
637
  ```
622
638
 
623
- - `to`:确认方 AID
624
- - `device_id`:触发 ack 的设备标识;legacy 客户端为空字符串
625
- - `slot_id`:触发 ack 的消费槽位;空字符串表示设备单实例或 legacy 路径
626
- - `ack_seq`:确认到的序列号(含该 seq 及之前的所有消息)
639
+ - `to`:确认方 AID
640
+ - `device_id`:触发 ack 的设备标识;legacy 客户端为空字符串
641
+ - `ack_seq`:确认到的序列号(含该 seq 及之前的所有消息)
627
642
 
628
643
  #### `event/message.recalled`
629
644
 
@@ -19,8 +19,10 @@
19
19
  | -32001 | Authentication failed(认证失败) | 检查凭据,重新登录 |
20
20
  | -32002 | Certificate/Nonce invalid(凭据无效) | 检查证书链或 nonce |
21
21
  | -32003 | Signature verification failed(签名验证失败) | 检查私钥,不重试 |
22
- | -32004 | Permission denied(权限拒绝) | 提示用户,不重试 |
23
- | -32005 | Authentication expired(Token 过期) | 刷新 token 或重新登录 |
22
+ | -32004 | Permission denied(权限拒绝) | 提示用户,不重试 |
23
+ | -32005 | Authentication expired(Token 过期) | 刷新 token 或重新登录 |
24
+
25
+ Owner relation RPC 在 `-32602 Invalid params` 的 `error.data.error_code` 中返回稳定错误码:`invalid_aid`、`invalid_aid_type`、`human_owner_forbidden`、`owner_required`、`self_owner_not_allowed`、`owner_not_verified`、`owner_type_forbidden`、`owner_relation_conflict`、`pending_operation_exists`、`operation_not_found`、`operation_expired`、`signature_invalid`、`signature_verification_unavailable`、`relation_version_conflict`、`idempotency_key_reuse`、`type_change_blocked`、`aid_binding_required`。`signature_verification_unavailable` 表示 owner 证书验证服务不可用;`type_change_blocked` 表示该 AID 仍是活动 owner;`aid_binding_required` 表示尚无已登记 type,需先完成 `aid_bind`。JSON-RPC 外层错误码仍为 `-32602`。
24
26
 
25
27
  ### 7.1.3 AUN 协议级错误码(连接与会话)
26
28
 
@@ -220,8 +222,21 @@ submitted → working → completed
220
222
  | input_required | | working, failed, canceled |
221
223
  | rejected | 是 | |
222
224
  | completed | 是 | |
223
- | failed | 是 | |
224
- | canceled | 是 | |
225
+ | failed | 是 | |
226
+ | canceled | 是 | |
227
+
228
+ ### 7.4.1 Owner relation operation 状态机
229
+
230
+ ```text
231
+ proof_pending
232
+ → agent_md_pending
233
+ → active
234
+
235
+ proof_pending / agent_md_pending
236
+ → expired
237
+ ```
238
+
239
+ `human` 注册在 agent.md 发布后进入 `not_applicable`;legacy AID 可处于 `legacy_unbound`,解绑后的关系为 `unbound`,因 owner 状态不可用时关系可标为 `unusable`,旧证书和数据保留。`owner_change` 从当前 `active` 关系创建 pending operation,三方签名和新 agent.md 激活后回到 `active`,`relation_version` 递增;CAS 不匹配或重复 pending operation 保持原关系不变。
225
240
 
226
241
  ## 7.5 处理原则
227
242
 
@@ -83,7 +83,7 @@ Group 服务是 AUN 协议的应用层扩展,提供多人群组通信能力。
83
83
 
84
84
  `mention-only` 必须基于结构化的 `payload.mentions` 判断,不得仅扫描文本中的 `@xxx`;`{ "scope": "all" }` 视为命中所有成员。该设置仅适用于群组,群 owner/admin 可写,普通成员只读。
85
85
 
86
- ### Member 对象
86
+ ### Member 对象
87
87
 
88
88
  | 字段 | 类型 | 说明 |
89
89
  |------|------|------|
@@ -91,7 +91,19 @@ Group 服务是 AUN 协议的应用层扩展,提供多人群组通信能力。
91
91
  | `group_id` | string | 群组 ID |
92
92
  | `role` | string | `"owner"` / `"admin"` / `"member"` |
93
93
  | `joined_at` | integer | 加入时间(Unix 秒) |
94
- | `last_ack_seq` | integer | 最后已读消息序号 |
94
+ | `last_ack_seq` | integer | 最后已读消息序号 |
95
+
96
+ ### Member Status 对象
97
+
98
+ | 字段 | 类型 | 说明 |
99
+ |------|------|------|
100
+ | `group_id` | string | 群组 ID |
101
+ | `aid` | string | 成员 AID |
102
+ | `online_status` | string | 成员上报的在线状态;未上报时为空字符串 |
103
+ | `work_status` | string | 成员上报的工作状态;未上报时为空字符串 |
104
+ | `updated_at` | integer | 最近一次状态上报时间(Unix 毫秒) |
105
+ | `last_message_at` | integer | 该成员在此群最后一条成功发送消息的时间(Unix 毫秒) |
106
+ | `last_payload_type` | string | 最后一条成功发送消息的 `payload.type` |
95
107
 
96
108
  ### Message 对象
97
109
 
@@ -119,8 +131,12 @@ Group 服务是 AUN 协议的应用层扩展,提供多人群组通信能力。
119
131
  | 设置角色 | ✅ | ❌ | ❌ |
120
132
  | 更新群信息 | ✅ | ✅ | ❌ |
121
133
  | 更新公告 | ✅ | ✅ | ❌ |
122
- | 审批申请 | ✅ | ✅ | ❌ |
123
- | 暂停/关闭群 | ✅ | ✅ | ❌ |
134
+ | 审批申请 | ✅ | ✅ | ❌ |
135
+ | 禁言/取消禁言 | ✅ | ✅(受角色层级限制) | ❌ |
136
+ | 屏蔽/取消屏蔽其他成员 | ✅ | ✅(受角色层级限制) | ❌ |
137
+ | 屏蔽/取消屏蔽自己 | ✅ | ✅ | ✅ |
138
+ | 上报自己状态/查询成员状态 | ✅ | ✅ | ✅ |
139
+ | 暂停/关闭群 | ✅ | ✅ | ❌ |
124
140
  | 转让群主 | ✅ | ❌ | ❌ |
125
141
  | Group FS 写入 | ✅ | 配置决定 | ❌ |
126
142
 
@@ -130,7 +146,9 @@ Group 服务是 AUN 协议的应用层扩展,提供多人群组通信能力。
130
146
 
131
147
  ### `group.create`
132
148
 
133
- 创建群组。
149
+ 创建群组。
150
+
151
+ SDK 高层建群流程必须支持崩溃恢复:命名群复用已持久化密钥并重放相同 `group_name + public_key` 的已提交结果;匿名群复用已持久化的创建上下文,使响应丢失后的重试返回同一数字群,再继续群身份绑定和 `agent.md` 上传。服务端必须原子提交群记录、群主成员、成员索引、入群设置、首个 `group.changed` 事件及匿名创建映射。直接调用 RPC 且没有 SDK 恢复上下文时,每次调用仍表示一次新的自动群创建。
134
152
 
135
153
  **参数**:
136
154
 
@@ -210,7 +228,7 @@ Group 服务是 AUN 协议的应用层扩展,提供多人群组通信能力。
210
228
 
211
229
  ### `group.suspend`
212
230
 
213
- 暂停群组,暂停期间不能发送消息。需要 admin 及以上权限。
231
+ 暂停群组。暂停期间 owner/admin 可以继续通过 `group.send`、`group.v2.send` 和 `group.thought.put` 发言;member 禁止发言,入群、邀请、申请审批等准入操作继续拒绝。需要 admin 及以上权限。
214
232
 
215
233
  **参数**:`group_id` (string, 必填)
216
234
 
@@ -293,9 +311,9 @@ Group 服务是 AUN 协议的应用层扩展,提供多人群组通信能力。
293
311
 
294
312
  **响应**:`{ "group": { ... }, "member": { ... } }`
295
313
 
296
- ### `group.transfer_owner`
297
-
298
- 转让群主身份。需要 **owner** 权限。
314
+ ### `group.transfer_owner`
315
+
316
+ 转让群主身份。需要 **owner** 权限。受让方无需手动确认,SDK 自动完成确认和转让收尾。
299
317
 
300
318
  **参数**:`group_id` (必填), `new_owner` (必填,新群主 AID;别名 `aid` 向后兼容)
301
319
 
@@ -332,13 +350,55 @@ Group 服务是 AUN 协议的应用层扩展,提供多人群组通信能力。
332
350
 
333
351
  **响应**:`{ "group_id": "g-abc123.agentid.pub", "unbanned_aid": "bob.agentid.pub" }`
334
352
 
335
- ### `group.get_banlist`
353
+ ### `group.get_banlist`
336
354
 
337
355
  获取封禁列表。需要 admin 及以上权限。
338
356
 
339
357
  **参数**:`group_id` (必填)
340
358
 
341
- **响应**:`{ "group_id": "g-abc123.agentid.pub", "items": [ ... ] }`
359
+ **响应**:`{ "group_id": "g-abc123.agentid.pub", "items": [ ... ] }`
360
+
361
+ 禁言和屏蔽是独立状态,可以同时设置。禁言禁止发送但不影响接收;屏蔽停止接收但不影响发送。
362
+
363
+ ### `group.block`
364
+
365
+ 屏蔽成员接收群消息。owner/admin 可以屏蔽其权限范围内的成员;成员可以屏蔽自己。屏蔽后,该成员不再收到实时消息 Push、离线消息 Push、Pull 或 E2EE wrap,但仍可向群内发送消息。
366
+
367
+ **参数**:`group_id`(必填)、`subject` 或 `aid`(必填;传入调用者自己的 AID 即可屏蔽自己)、`reason`(可选)。
368
+
369
+ **响应**:`{ "group_id": "g-abc123.agentid.pub", "group_aid": "g-abc123.agentid.pub", "block": { "group_id": "g-abc123.agentid.pub", "subject": "bob.agentid.pub", "blocked_by": "alice.agentid.pub", "reason": "", "created_at": 1234567890000 } }`
370
+
371
+ ### `group.unblock`
372
+
373
+ 取消屏蔽。owner/admin 可以取消其权限范围内成员的屏蔽;成员可以取消自己的屏蔽。
374
+
375
+ **参数**:`group_id`(必填)、`subject` 或 `aid`(必填;传入调用者自己的 AID 即可取消自己的屏蔽)。
376
+
377
+ **响应**:`{ "group_id": "g-abc123.agentid.pub", "group_aid": "g-abc123.agentid.pub", "subject": "bob.agentid.pub", "status": "removed" }`
378
+
379
+ ### `group.get_blocklist`
380
+
381
+ 获取群屏蔽列表。需要 admin 及以上权限。
382
+
383
+ **参数**:`group_id`(必填)
384
+
385
+ **响应**:`{ "group_id": "g-abc123.agentid.pub", "group_aid": "g-abc123.agentid.pub", "items": [ ... ], "total": 1, "page": 1, "size": 1 }`
386
+
387
+ ### `group.report_status`
388
+
389
+ 上报调用者在指定群内的 `online_status` 和 `work_status`。调用者只能更新自己的状态,`updated_at` 由服务端记录;`last_message_at` 和 `last_payload_type` 由服务端在消息发送成功后维护。
390
+
391
+ **参数**:`group_id`(必填)、`online_status`(必填)、`work_status`(必填)。
392
+
393
+ **响应**:`{ "group_id": "g-abc123.agentid.pub", "group_aid": "g-abc123.agentid.pub", "status": { ... } }`
394
+
395
+ ### `group.get_member_statuses`
396
+
397
+ 查询群内所有成员状态。调用者必须是群成员;响应包含未上报状态的成员。
398
+
399
+ **参数**:`group_id`(必填)
400
+
401
+ **响应**:`{ "group_id": "g-abc123.agentid.pub", "group_aid": "g-abc123.agentid.pub", "items": [ { "group_id": "g-abc123.agentid.pub", "aid": "alice.agentid.pub", "online_status": "online", "work_status": "busy", "updated_at": 1234567890000, "last_message_at": 1234567890123, "last_payload_type": "text" } ] }`
342
402
 
343
403
  ---
344
404
 
@@ -389,7 +449,7 @@ Group 服务是 AUN 协议的应用层扩展,提供多人群组通信能力。
389
449
  ```
390
450
 
391
451
  **设计约束**:
392
- - 群 `status=suspended` 时拒绝发送
452
+ - 群 `status=suspended` 时仅 owner/admin 可以发送,member 发送会被拒绝
393
453
  - 消息 ID 自动生成(格式:`gm-{uuid}`),客户端无需提供
394
454
 
395
455
  ### `group.pull`
@@ -631,7 +691,7 @@ Group FS 是群文件系统的唯一对外模型,所有群文件浏览、创
631
691
 
632
692
  ---
633
693
 
634
- ## 10.12 在线状态
694
+ ## 10.12 在线状态与群内成员状态
635
695
 
636
696
  群组在线状态是 per-AID 的全局状态(非 per-group)。在线索引由 Gateway 的 `client.online` / `client.offline` 事件驱动,Group 服务消费这些事件维护在线状态;客户端不需要也不能调用单独的上线、下线或心跳 RPC。
637
697
 
@@ -643,7 +703,9 @@ Group FS 是群文件系统的唯一对外模型,所有群文件浏览、创
643
703
 
644
704
  **响应**:`{ "group_id": "g-abc123.agentid.pub", "members": [ ... ], "items": [ ... ], "online_members": [ ... ], "online_count": 2, "total": 10, "page": 1, "size": 10 }`
645
705
 
646
- 字段约定:`members` 是主字段;`items` 和 `online_members` 是兼容别名,内容与 `members` 完全相同。
706
+ 字段约定:`members` 是主字段;`items` 和 `online_members` 是兼容别名,内容与 `members` 完全相同。
707
+
708
+ `group.get_online_members` 返回 Gateway 在线索引中的全局连接状态。`group.report_status` / `group.get_member_statuses` 管理成员在单个群内主动上报的在线/工作状态及最后发言摘要,两套状态来源相互独立。
647
709
 
648
710
  ---
649
711
 
@@ -725,8 +787,10 @@ Group 服务通过 `event/group.*` 事件推送变更通知给相关 AID。
725
787
  | `invite_code_created` | 邀请码创建 |
726
788
  | `invite_code_used` | 邀请码使用 |
727
789
  | `invite_code_revoked` | 邀请码撤销 |
728
- | `member_banned` | 成员被封禁 |
729
- | `member_unbanned` | 成员解除封禁 |
790
+ | `member_banned` | 成员被封禁 |
791
+ | `member_unbanned` | 成员解除封禁 |
792
+ | `member_blocked` | 成员被屏蔽 |
793
+ | `member_unblocked` | 成员取消屏蔽 |
730
794
  | `suspended` | 群组暂停 |
731
795
  | `resumed` | 群组恢复 |
732
796
  | `dissolved` | 群组解散 |
@@ -807,4 +871,3 @@ Group 服务通过 `event/group.*` 事件推送变更通知给相关 AID。
807
871
  - **Group FS**:群文件能力统一由 `group.fs.*` 提供;不再提供独立资源审批 RPC。
808
872
  - **在线状态**:通过 `group.get_online_members` 查询当前在线成员列表。
809
873
  - **Group FS 系统目录保护**:`memberdata` 是 Group FS 视图层的虚拟系统目录;根节点和成员槽位根不得被普通文件操作删除、覆盖或重命名。成员槽位子路径映射到成员个人 Storage 的 `group_data/{group_aid}`,只能通过 `group.fs.*` 间接访问。完整保护规则见 [16-系统目录保护方案.md](16-系统目录保护方案.md)。
810
-
@@ -130,7 +130,7 @@ Storage 服务是 AUN 协议的应用层扩展,提供对象存储能力。负
130
130
 
131
131
  **权限**:仅所有者可列。
132
132
 
133
- ### `storage.get_quota`
133
+ ### `storage.get_quota`
134
134
 
135
135
  查询存储配额使用情况。
136
136
 
@@ -142,7 +142,30 @@ Storage 服务是 AUN 协议的应用层扩展,提供对象存储能力。负
142
142
 
143
143
  **响应**:`{ owner_aid, used_bytes, object_count, quota_bytes }`
144
144
 
145
- **权限**:仅所有者可查。
145
+ **权限**:仅所有者可查。
146
+
147
+ ### `storage.relation_backup_provision`
148
+
149
+ 由 Auth 服务在 external owner relation 激活或重建时内部调用,普通客户端不得调用。请求必须带 `_caller_id="auth"`,参数如下:
150
+
151
+ | 参数 | 类型 | 必需 | 说明 |
152
+ |------|------|:----:|------|
153
+ | `owner_aid` | string | 是 | 外部 owner AID |
154
+ | `subject_aid` | string | 是 | 被管理的 subject AID;与 owner 不同 |
155
+ | `proof_id` | string | 是 | 当前 active ownership proof |
156
+ | `relation_version` | integer | 是 | 当前关系版本,>=1 |
157
+
158
+ 服务端在 owner 的 `default` bucket 创建或复用固定命名空间 `.aun/subjects/<lowercase_subject_aid>`,并写入 subject 的 `rw` ACL。成功响应包含 `schema=aun.relation-backup-namespace.v1`、`owner_aid`、`subject_aid`、`proof_id`、`relation_version`、`bucket=default`、`path`、`acl_source=ownership_relation`、`acl_generation`、`status=ready`、`on_revoke=retain_data_revoke_acl` 和 `data_retained=true`。首次 provision 的 `acl_generation` 为 1;同一 proof/version 重复调用幂等。
159
+
160
+ ### `storage.relation_backup_revoke`
161
+
162
+ 由 Auth 服务内部调用,参数为 `owner_aid`、`subject_aid` 和可选 `expected_relation_version`。服务端只移除 subject 的 relation ACL,不删除命名空间或其中数据,响应 `status=retained`、`data_retained=true`,并递增 `acl_generation`。记录不存在返回 `-32008`;Auth 之外的调用返回 `-32004`。
163
+
164
+ ### `storage.relation_backup_status`
165
+
166
+ 查询关系备份命名空间元数据,不返回目录内容。请求参数:`subject_aid` 必填,`owner_aid` 可选。调用者必须是 owner 或 subject;其它调用返回 `-32004`。未创建记录返回 `status=pending`、`acl_generation=0`、`data_retained=false`;已撤销记录返回 `status=retained`,数据仍保留。
167
+
168
+ 关系备份目录的权限约束:subject 仅在关系 `ready` 时访问自己的 `.aun/subjects/<subject>/` 后代,不能枚举 `.aun/subjects/` 根或其它 subject 目录,不能删除自己的 subject 根目录,也不能修改 ACL、visibility、token、share 或 mount。owner 可读写目录数据,但不能通过普通 Storage RPC 修改关系 ACL。
146
169
 
147
170
  ---
148
171