@agentunion/fastaun-browser 0.3.0 → 0.3.1

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 CHANGED
@@ -6,6 +6,22 @@
6
6
 
7
7
  ---
8
8
 
9
+ ## 0.3.1 — 2026-05-22
10
+
11
+ ### Added
12
+ - **`auth.checkAid` handler**:本地证书自检 + 远端注册状态查询(与 Node 版对齐)
13
+ - **RPC trace 增强(浏览器版本)**:`RPCTransport` 增加 `setTraceMode()` / `setTraceObserver()`;`sortTraceSpansForDisplay` / `formatTraceTree` / `traceDisplay` 树状展示
14
+ - **V2 群组 SPK 生命周期**:`V2KeyStore.saveGroupSPK` / `loadGroupSPK` / `loadCurrentGroupSPK` 基于 IndexedDB 持久化;`V2Session.ensureGroupSPK` / `ensureGroupRegistered` / `rotateGroupSPK` / `getGroupDecryptKeys`;`DESTROY_DELAY_MS = 7d`
15
+ - **V2 P2P push 解密**:`AUNClient` 增加 push payload 就地解密路径,失败回退到 pull
16
+
17
+ ### Changed
18
+ - **`SeqTracker.forceContiguousSeq`**:原 `contiguousSeq = minSeq` 跳过空洞(会丢消息),改为 `contiguousSeq = minSeq - 1` 由连续前缀自然推进
19
+
20
+ ### Fixed
21
+ - short RPC 请求增加 `debug` 完整报文日志,便于跨语言诊断
22
+
23
+ ---
24
+
9
25
  ## 0.3.0 — 2026-05-21 ⚠️ BREAKING CHANGE
10
26
 
11
27
  > **V2-only 版本**:移除全部 V1 E2EE(含群组加密),新增 V2 加密原语,API 不向后兼容。
package/README.md CHANGED
@@ -511,7 +511,6 @@ SDK 内部已自动处理以下群组 E2EE 场景:
511
511
  | `message.received` | P2P 消息,SDK 已优先自动解密 |
512
512
  | `message.undecryptable` | 无法解密的 P2P 消息 |
513
513
  | `message.recalled` | 撤回事件 |
514
- | `message.ack` | ack 事件 |
515
514
  | `group.message_created` | 群消息,SDK 已优先自动解密 |
516
515
  | `group.message_undecryptable` | 无法解密的群消息 |
517
516
  | `group.changed` | 群组事件 |
@@ -6,6 +6,22 @@
6
6
 
7
7
  ---
8
8
 
9
+ ## 0.3.1 — 2026-05-22
10
+
11
+ ### Added
12
+ - **`auth.checkAid` handler**:本地证书自检 + 远端注册状态查询(与 Node 版对齐)
13
+ - **RPC trace 增强(浏览器版本)**:`RPCTransport` 增加 `setTraceMode()` / `setTraceObserver()`;`sortTraceSpansForDisplay` / `formatTraceTree` / `traceDisplay` 树状展示
14
+ - **V2 群组 SPK 生命周期**:`V2KeyStore.saveGroupSPK` / `loadGroupSPK` / `loadCurrentGroupSPK` 基于 IndexedDB 持久化;`V2Session.ensureGroupSPK` / `ensureGroupRegistered` / `rotateGroupSPK` / `getGroupDecryptKeys`;`DESTROY_DELAY_MS = 7d`
15
+ - **V2 P2P push 解密**:`AUNClient` 增加 push payload 就地解密路径,失败回退到 pull
16
+
17
+ ### Changed
18
+ - **`SeqTracker.forceContiguousSeq`**:原 `contiguousSeq = minSeq` 跳过空洞(会丢消息),改为 `contiguousSeq = minSeq - 1` 由连续前缀自然推进
19
+
20
+ ### Fixed
21
+ - short RPC 请求增加 `debug` 完整报文日志,便于跨语言诊断
22
+
23
+ ---
24
+
9
25
  ## 0.3.0 — 2026-05-21 ⚠️ BREAKING CHANGE
10
26
 
11
27
  > **V2-only 版本**:移除全部 V1 E2EE(含群组加密),新增 V2 加密原语,API 不向后兼容。
@@ -0,0 +1,542 @@
1
+ # AUN RPC Trace 增强设计
2
+
3
+ **日期**: 2026-05-22
4
+ **范围**: Gateway + Message + Auth + CA + Group + Python SDK
5
+ **目标**: 补全 RPC trace 诊断信息,从"只有路径和耗时"到"能定位业务失败原因"
6
+
7
+ ---
8
+
9
+ ## 问题现状
10
+
11
+ 当前 trace 输出示例:
12
+
13
+ ```
14
+ [TRACE][message.v2.put_peer_pk][error] total=54ms trace_id=93643d8d922d3d49a86345b8c267c178
15
+ ├─ sdk.send dur=0ms @00:24:29.197
16
+ ├─ gateway.relay_in dur=0ms @00:24:29.378
17
+ ├─ ca.process dur=2ms @00:24:29.382
18
+ ├─ message.process dur=7ms @00:24:29.380
19
+ ├─ gateway.relay_out dur=10ms @00:24:29.378
20
+ └─ sdk.recv dur=54ms
21
+ ```
22
+
23
+ **缺陷:**
24
+ 1. 只能看到"经过了哪些模块",看不到"每个模块做了什么"
25
+ 2. `ca.process dur=2ms` 无法知道查的是哪个 AID、什么条件、结果是否找到
26
+ 3. `message.process dur=7ms` 无法知道调用了哪个嵌套 RPC、为什么失败
27
+ 4. 单行 `process` span 无法区分"进入"和"退出",嵌套关系不清晰
28
+
29
+ **根本原因:**
30
+ - 服务端 span 只有 `node`、`ts`、`action=process`、`ms` 四个字段
31
+ - 没有业务诊断字段(aid、method、found、error_code 等)
32
+ - SDK 展示逻辑按"平铺列表"而非"调用树"
33
+
34
+ ---
35
+
36
+ ## 设计方案
37
+
38
+ ### 1. Span 结构改造
39
+
40
+ #### 1.1 Enter/Exit 语义
41
+
42
+ 每个服务产生 **两个 span**:
43
+
44
+ **Enter span(承载所有诊断信息):**
45
+ ```python
46
+ {
47
+ "node": "message", # 模块名
48
+ "ts": 1234567890123, # 毫秒时间戳
49
+ "action": "enter", # 固定 "enter"
50
+ "method": "v2.put_peer_pk", # RPC 方法短名
51
+ # 业务诊断字段(按模块定制,尽可能详细)
52
+ "caller_aid": "yayi2000.agentid.pub",
53
+ "peer_aid": "yayi2000.agentid.pub",
54
+ "key_source": "peer_device_prekey",
55
+ "spk_id": "sha256:abc123ab",
56
+ "device_id": "device-xyz",
57
+ }
58
+ ```
59
+
60
+ **Exit span:**
61
+ ```python
62
+ {
63
+ "node": "message",
64
+ "ts": 1234567890130,
65
+ "action": "exit",
66
+ "ms": 7, # 耗时(必需)
67
+ "status": "error", # ok / error(必需)
68
+ # 失败时补充错误信息 + 上下文
69
+ "error_code": -32603,
70
+ "error_msg": "AID cert not found",
71
+ "peer_aid": "yayi2000.agentid.pub", # 失败相关的关键上下文
72
+ "method": "v2.put_peer_pk",
73
+ # 成功时补充关键结果(可选)
74
+ "found": false, # CA 查询结果
75
+ "delivered_count": 2, # Message 发送结果
76
+ }
77
+ ```
78
+
79
+ **设计原则:**
80
+ - **Enter span 承载完整上下文**,方便定位问题根因
81
+ - **Exit span 关注结果和性能**:
82
+ - 成功时:`ms`、`status=ok`、关键结果字段(found/delivered_count)
83
+ - 失败时:`ms`、`status=error`、`error_code`、`error_msg`、**失败相关的上下文字段**(aid/method/peer_aid 等)
84
+ - SDK 展示时,enter 行显示完整诊断信息,exit 行显示结果和耗时
85
+
86
+ #### 1.2 嵌套调用处理
87
+
88
+ 当 Message 调用 CA 时:
89
+ - Message 的 `_current_trace.child_spans` 自动收集 CA 的 enter/exit span
90
+ - Message exit 时,将 child_spans 合并到响应的 `_trace.spans` 列表
91
+ - SDK 收到后按 ts 排序,自动识别嵌套关系
92
+
93
+ #### 1.3 安全字段白名单
94
+
95
+ **允许放入 span:**
96
+ - ✅ aid、method、curve、lifecycle_state、found、error_code
97
+ - ✅ cert_sn 前缀(前 8 位)、route、namespace、instance_id
98
+ - ✅ group_id、member_count、delivered_count
99
+
100
+ **严格禁止:**
101
+ - ❌ token、私钥、证书 PEM、签名原文
102
+ - ❌ challenge nonce、密码、refresh_token
103
+
104
+ ---
105
+
106
+ ### 2. 各模块补充字段
107
+
108
+ #### 2.1 Gateway (relay.py)
109
+
110
+ **Enter span (`relay_in`):**
111
+ ```python
112
+ {
113
+ "node": "gateway",
114
+ "action": "enter",
115
+ "ts": <timestamp>,
116
+ # 详细诊断信息
117
+ "route": "service_plane", # direct / service_plane / kernel / fallback
118
+ "namespace": "message",
119
+ "method": "v2.put_peer_pk",
120
+ "aid": "yayi2000.agentid.pub",
121
+ "instance_id": "message#1", # service_plane 时有值
122
+ "connection_id": "conn-abc123",
123
+ "device_id": "device-xyz",
124
+ }
125
+ ```
126
+
127
+ **Exit span:**
128
+ ```python
129
+ {
130
+ "node": "gateway",
131
+ "action": "exit",
132
+ "ts": <timestamp>,
133
+ "ms": 10, # 耗时(必需)
134
+ "status": "error", # ok / error(必需)
135
+ # 失败时补充错误信息 + 上下文
136
+ "error_code": -32603,
137
+ "error_msg": "AID cert not found",
138
+ "method": "v2.put_peer_pk",
139
+ "aid": "yayi2000.agentid.pub",
140
+ }
141
+ ```
142
+
143
+ **修改位置:**
144
+ - `relay.py:844` — relay_in span 补字段
145
+ - `relay.py:962` — relay_out span 补字段
146
+
147
+ #### 2.2 Message (entry.py)
148
+
149
+ **Enter span:**
150
+ ```python
151
+ {
152
+ "node": "message",
153
+ "action": "enter",
154
+ "ts": <timestamp>,
155
+ # 详细诊断信息
156
+ "method": "v2.put_peer_pk",
157
+ "caller_aid": "yayi2000.agentid.pub",
158
+ "peer_aid": "yayi2000.agentid.pub",
159
+ "key_source": "peer_device_prekey",
160
+ "spk_id": "sha256:abc123ab",
161
+ "device_id": "device-xyz",
162
+ # 或按方法不同:
163
+ # "to_aid" / "from_aid" / "group_id" / "message_id"
164
+ }
165
+ ```
166
+
167
+ **Exit span:**
168
+ ```python
169
+ {
170
+ "node": "message",
171
+ "action": "exit",
172
+ "ts": <timestamp>,
173
+ "ms": 7, # 耗时(必需)
174
+ "status": "error", # ok / error(必需)
175
+ # 失败时补充错误信息 + 上下文
176
+ "error_code": -32603,
177
+ "error_msg": "AID cert not found",
178
+ "method": "v2.put_peer_pk",
179
+ "peer_aid": "yayi2000.agentid.pub",
180
+ # 成功时补充关键结果
181
+ "found": true, # bootstrap 方法
182
+ "delivered_count": 2, # send 方法
183
+ "message_id": "msg-xyz",
184
+ }
185
+ ```
186
+
187
+ **修改位置:**
188
+ - `entry.py:199-268` — `_TracingWS` 类改造
189
+ - `__init__` 记录 enter 时间
190
+ - `_inject_trace` 改成生成 enter + exit 两个 span
191
+ - enter span 从 `params` 提取业务字段
192
+ - exit span 从 `payload` 提取 status/error
193
+
194
+ #### 2.3 Auth (entry.py)
195
+
196
+ **Enter span:**
197
+ ```python
198
+ {
199
+ "node": "auth",
200
+ "action": "enter",
201
+ "ts": <timestamp>,
202
+ # 详细诊断信息
203
+ "method": "verify", # 或 login_phase1 / login_phase2 / create_aid
204
+ "aid": "yayi2000.agentid.pub",
205
+ "auth_method": "aid", # pairing_code / kite_token / aid
206
+ "device_id": "device-xyz",
207
+ "client_nonce": "nonce-abc...", # 前 16 位
208
+ }
209
+ ```
210
+
211
+ **Exit span:**
212
+ ```python
213
+ {
214
+ "node": "auth",
215
+ "action": "exit",
216
+ "ts": <timestamp>,
217
+ "ms": 15, # 耗时(必需)
218
+ "status": "ok", # ok / error(必需)
219
+ # 成功时补充
220
+ "success": true, # verify 方法
221
+ "created": false, # create_aid 方法(幂等标识)
222
+ # 失败时补充
223
+ "error_code": -32001,
224
+ "error_msg": "invalid signature",
225
+ }
226
+ ```
227
+
228
+ **修改位置:**
229
+ - Auth 模块当前没有 `_TracingWS` 封装,需要新增或复用 Message 的模式
230
+
231
+ #### 2.4 CA (entry.py)
232
+
233
+ **Enter span:**
234
+ ```python
235
+ {
236
+ "node": "ca",
237
+ "action": "enter",
238
+ "ts": <timestamp>,
239
+ # 详细诊断信息
240
+ "method": "get_cert",
241
+ "aid": "yayi2000.agentid.pub",
242
+ "curve": "P-256",
243
+ "lifecycle_state": "active_signing",
244
+ "cert_sn": "abc123...", # 按序列号查询时
245
+ "cert_fingerprint": "sha256:abc123ab...", # 按指纹查询时(前 16 位)
246
+ }
247
+ ```
248
+
249
+ **Exit span:**
250
+ ```python
251
+ {
252
+ "node": "ca",
253
+ "action": "exit",
254
+ "ts": <timestamp>,
255
+ "ms": 2, # 耗时(必需)
256
+ "status": "ok", # ok / error(必需)
257
+ # 成功时补充
258
+ "found": true,
259
+ "cert_sn_prefix": "abc123ab", # 找到时返回前 8 位
260
+ "lifecycle_state": "active_signing",
261
+ # 失败时补充错误信息 + 上下文
262
+ "found": false,
263
+ "error_code": -32002,
264
+ "error_msg": "certificate not found",
265
+ "method": "get_cert",
266
+ "aid": "yayi2000.agentid.pub",
267
+ "curve": "P-256",
268
+ }
269
+ ```
270
+
271
+ **修改位置:**
272
+ - CA 模块当前没有 `_TracingWS` 封装,需要新增
273
+
274
+ #### 2.5 Group (entry.py)
275
+
276
+ **Enter span:**
277
+ ```python
278
+ {
279
+ "node": "group",
280
+ "action": "enter",
281
+ "ts": <timestamp>,
282
+ # 详细诊断信息
283
+ "method": "create",
284
+ "group_id": "group-abc123",
285
+ "caller_aid": "alice.aid.com",
286
+ "member_aids": ["alice.aid.com", "bob.aid.com", "carol.aid.com"], # 或 member_count
287
+ "group_name": "Project Team",
288
+ }
289
+ ```
290
+
291
+ **Exit span:**
292
+ ```python
293
+ {
294
+ "node": "group",
295
+ "action": "exit",
296
+ "ts": <timestamp>,
297
+ "ms": 12, # 耗时(必需)
298
+ "status": "ok", # ok / error(必需)
299
+ # 成功时补充
300
+ "group_id": "group-abc123",
301
+ "member_count": 3,
302
+ # 失败时补充错误信息 + 上下文
303
+ "error_code": -32603,
304
+ "error_msg": "member not found",
305
+ "method": "create",
306
+ "caller_aid": "alice.aid.com",
307
+ }
308
+ ```
309
+
310
+ **修改位置:**
311
+ - Group 模块当前没有 `_TracingWS` 封装,需要新增
312
+
313
+ ---
314
+
315
+ ### 3. SDK 展示改造(Python)
316
+
317
+ #### 3.1 目标效果
318
+
319
+ ```
320
+ [TRACE][message.v2.put_peer_pk][error] total=54ms trace_id=93643d8d922d3d49a86345b8c267c178
321
+ ├─ sdk.send @00:24:29.197
322
+ ├─ gateway.enter route=service_plane namespace=message @00:24:29.378
323
+ ├─ message.enter method=v2.put_peer_pk peer_aid=yayi2000.agentid.pub @00:24:29.380
324
+ │ ├─ ca.enter method=get_cert aid=yayi2000.agentid.pub curve=P-256 lifecycle=active_signing @00:24:29.382
325
+ │ └─ ca.exit status=not_found found=false dur=2ms @00:24:29.384
326
+ ├─ message.exit status=error error_code=-32603 error="AID cert not found" dur=7ms @00:24:29.387
327
+ ├─ gateway.exit status=error dur=10ms @00:24:29.388
328
+ └─ sdk.recv dur=54ms
329
+ ```
330
+
331
+ #### 3.2 实现要点
332
+
333
+ **树状结构识别:**
334
+ 1. 按 `ts` 排序所有 span
335
+ 2. 维护栈:遇到 `action=enter` 入栈,遇到 `action=exit` 出栈
336
+ 3. 栈深度决定缩进层级
337
+ 4. exit span 展示 duration(从对应 enter span 计算)
338
+
339
+ **字段展示规则:**
340
+ - enter span:展示关键业务字段(aid、method、route 等)
341
+ - exit span:展示结果字段(status、found、error_code、dur)
342
+ - 单行最多展示 3-4 个关键字段,避免过长
343
+
344
+ **向后兼容:**
345
+ - 旧格式 `action=process`:按单行展示,dur 直接取 `ms` 字段
346
+ - 新格式 enter/exit:按树状展示
347
+ - 混合格式:分别处理
348
+
349
+ **修改位置:**
350
+ - `python/src/aun_core/transport.py:268-281` — `_trace_observer` 回调
351
+ - 新增 `_format_trace_tree(spans)` 函数,返回多行字符串
352
+
353
+ ---
354
+
355
+ ### 4. 实现计划
356
+
357
+ #### Phase 1: 服务端 span 结构改造
358
+
359
+ **Task 1.1: Message 模块 enter/exit span**
360
+ - 修改 `_TracingWS` 类,改造 `_inject_trace` 方法
361
+ - enter span 从 `params` 提取 `method`、`caller_aid`、`peer_aid`/`to_aid`/`group_id`
362
+ - exit span 从 `payload` 提取 `status`、`error_code`、`found`/`delivered_count`
363
+ - 测试:`message.v2.put_peer_pk` 失败时 trace 包含 `peer_aid` 和 `error_code`
364
+
365
+ **Task 1.2: CA 模块 enter/exit span**
366
+ - 新增 `_TracingWS` 封装(复用 Message 模式)
367
+ - enter span 提取 `aid`、`cert_sn`、`curve`、`lifecycle_state`
368
+ - exit span 提取 `found`、`cert_sn_prefix`(前 8 位)
369
+ - 测试:`ca.get_cert` 查询失败时 trace 包含 `aid` 和 `found=false`
370
+
371
+ **Task 1.3: Auth 模块 enter/exit span**
372
+ - 新增 `_TracingWS` 封装
373
+ - enter span 提取 `method`、`aid`、`auth_method`
374
+ - exit span 提取 `success`、`created`
375
+ - 测试:`auth.verify` 失败时 trace 包含 `aid` 和 `auth_method`
376
+
377
+ **Task 1.4: Group 模块 enter/exit span**
378
+ - 新增 `_TracingWS` 封装
379
+ - enter span 提取 `method`、`group_id`、`caller_aid`、`member_count`
380
+ - exit span 提取 `group_id`、`member_count`
381
+ - 测试:`group.create` 成功时 trace 包含 `group_id` 和 `member_count`
382
+
383
+ **Task 1.5: Gateway relay span 补字段**
384
+ - `relay_in` span 补充 `route`、`namespace`、`method`、`aid`、`instance_id`
385
+ - `relay_out` span 补充 `status`、`error_code`
386
+ - 测试:service_plane 路由时 trace 包含 `route=service_plane` 和 `instance_id`
387
+
388
+ #### Phase 2: SDK 展示改造
389
+
390
+ **Task 2.1: 树状展示逻辑**
391
+ - 新增 `_format_trace_tree(spans)` 函数
392
+ - 按 `ts` 排序,维护栈识别嵌套
393
+ - enter/exit 配对,exit 时计算 duration
394
+ - 返回多行字符串(带缩进)
395
+
396
+ **Task 2.2: 字段展示规则**
397
+ - enter span:展示 `method`、`aid`、`route` 等关键字段
398
+ - exit span:展示 `status`、`found`、`error_code`、`dur`
399
+ - 单行最多 3-4 个字段
400
+
401
+ **Task 2.3: 向后兼容**
402
+ - 识别旧格式 `action=process`,按单行展示
403
+ - 混合格式分别处理
404
+
405
+ **Task 2.4: 集成到 transport.py**
406
+ - 修改 `_trace_observer` 回调,调用 `_format_trace_tree`
407
+ - 输出到日志(`self._log.info`)
408
+
409
+ #### Phase 3: 测试验证
410
+
411
+ **Task 3.1: 单元测试**
412
+ - `test_trace_span_enter_exit.py` — 验证 enter/exit span 生成
413
+ - `test_trace_tree_format.py` — 验证 SDK 树状展示
414
+
415
+ **Task 3.2: 集成测试**
416
+ - 运行 `python -X utf8 tests/integration_test_e2ee.py`
417
+ - 验证 `message.v2.put_peer_pk` 失败时 trace 包含完整诊断信息
418
+ - 验证嵌套调用(message → ca)的 span 正确合并
419
+
420
+ **Task 3.3: 手动测试**
421
+ - `aun login yayi2000.agentid.pub` 触发 `put_peer_pk` 失败
422
+ - 检查日志输出是否包含 `peer_aid`、`ca.enter`、`found=false`、`error_code`
423
+
424
+ ---
425
+
426
+ ### 5. 向后兼容
427
+
428
+ **旧 SDK 收到新 span:**
429
+ - 忽略不认识的字段(`action=enter/exit`、业务字段)
430
+ - 仍能展示基本路径和耗时
431
+
432
+ **新 SDK 收到旧 span:**
433
+ - 识别 `action=process`,按单行展示
434
+ - 不影响现有功能
435
+
436
+ **trace mode 不变:**
437
+ - 仍为 `off/log/diag` 三档
438
+ - 不引入新模式
439
+
440
+ ---
441
+
442
+ ### 6. 安全审查
443
+
444
+ **禁止字段清单:**
445
+ - token、refresh_token、access_token
446
+ - 私钥(private_key、priv、secret)
447
+ - 证书 PEM(cert_pem、cert、certificate)
448
+ - 签名原文(signature、sig_raw)
449
+ - challenge nonce、密码(password、pwd)
450
+
451
+ **允许字段清单:**
452
+ - aid、method、curve、lifecycle_state
453
+ - found、error_code、error_msg(不含敏感信息)
454
+ - cert_sn 前缀(前 8 位)
455
+ - route、namespace、instance_id
456
+ - group_id、member_count、delivered_count
457
+
458
+ **审查机制:**
459
+ - 代码审查时检查所有 span 字段来源
460
+ - 禁止直接 `span.update(params)` 全量复制
461
+ - 必须显式白名单提取
462
+
463
+ ---
464
+
465
+ ### 7. 性能影响
466
+
467
+ **额外开销:**
468
+ - 每个 RPC 多生成 1 个 span(enter + exit 共 2 个,原来 1 个)
469
+ - 每个 span 增加 3-5 个业务字段(约 50-100 字节)
470
+ - SDK 展示增加树状格式化(O(n log n) 排序 + O(n) 遍历)
471
+
472
+ **预估影响:**
473
+ - diag 模式下单次 RPC 增加 ~200 字节网络传输
474
+ - SDK 格式化耗时 <1ms(100 个 span 以内)
475
+ - 对 off/log 模式无影响(不生成 span)
476
+
477
+ **优化措施:**
478
+ - span 数量上限保持 32 个(已有限制)
479
+ - 字段值截断(error_msg 最多 200 字符)
480
+ - 仅 diag 模式生成详细字段
481
+
482
+ ---
483
+
484
+ ## 实施顺序
485
+
486
+ 1. **Phase 1.1-1.2**:Message + CA(最高优先级,覆盖 80% 失败场景)
487
+ 2. **Phase 2**:SDK 展示改造(让 Phase 1 的字段可见)
488
+ 3. **Phase 3.2-3.3**:集成测试 + 手动验证
489
+ 4. **Phase 1.3-1.5**:Auth + Group + Gateway(补全剩余模块)
490
+ 5. **Phase 3.1**:单元测试(回归保护)
491
+
492
+ ---
493
+
494
+ ## 成功标准
495
+
496
+ **功能完整性:**
497
+ - ✅ `message.v2.put_peer_pk` 失败时,trace 包含 `peer_aid` 和 `ca.get_cert` 的 `found=false`
498
+ - ✅ `ca.get_cert` 查询失败时,trace 包含 `aid`、`curve`、`lifecycle_state`
499
+ - ✅ SDK 展示为树状结构,嵌套调用正确缩进
500
+ - ✅ enter/exit span 配对,exit 展示 duration
501
+
502
+ **向后兼容:**
503
+ - ✅ 旧 SDK 收到新 span 不报错
504
+ - ✅ 新 SDK 收到旧 span 降级展示
505
+
506
+ **安全合规:**
507
+ - ✅ 所有 span 字段通过白名单审查
508
+ - ✅ 不包含 token、私钥、证书 PEM、签名原文
509
+
510
+ **性能可接受:**
511
+ - ✅ diag 模式下单次 RPC 增加传输 <500 字节
512
+ - ✅ SDK 格式化耗时 <5ms
513
+
514
+ ---
515
+
516
+ ## 风险与缓解
517
+
518
+ **风险 1:span 数量爆炸**
519
+ - 缓解:保持 32 个上限,超出时截断最早的 span
520
+
521
+ **风险 2:敏感信息泄露**
522
+ - 缓解:代码审查 + 白名单机制 + 单元测试覆盖
523
+
524
+ **风险 3:向后兼容性破坏**
525
+ - 缓解:旧 SDK 忽略新字段,新 SDK 识别旧格式
526
+
527
+ **风险 4:性能回退**
528
+ - 缓解:仅 diag 模式生成详细字段,off/log 模式不变
529
+
530
+ ---
531
+
532
+ ## 后续扩展
533
+
534
+ **Phase 4(可选):**
535
+ - 其他语言 SDK(Go/TS/JS/C++)展示改造
536
+ - 其他服务模块(Storage/Stream/Mail)span 补全
537
+ - Trace 聚合分析工具(按 trace_id 查询完整链路)
538
+
539
+ **Phase 5(可选):**
540
+ - Trace 持久化(写入 ClickHouse/Elasticsearch)
541
+ - Trace 可视化(Web UI 展示调用树)
542
+ - Trace 告警(失败率/耗时异常自动通知)
@@ -254,7 +254,7 @@
254
254
  }
255
255
  ```
256
256
 
257
- **说明**:`ack_seq` 仅增不减。现代连接按 `(aid, device_id, slot_id)` 维护 ack 游标;未携带 `device_id` 的 legacy 连接继续走 per-AID 兼容路径。显式传入的 `device_id` / `slot_id` 若与连接认证上下文不一致,服务端 **MUST** 拒绝请求。
257
+ **说明**:`ack_seq` 仅增不减。现代连接按 `(aid, device_id, slot_id)` 维护 ack 游标;未携带 `device_id` 的 legacy 连接继续走 per-AID 兼容路径。显式传入的 `device_id` / `slot_id` 若与连接认证上下文不一致,服务端 **MUST** 拒绝请求。`message.ack` 只更新接收方消费游标,服务端 **MUST NOT** 向发送方或其他客户端发布 ack 通知事件。
258
258
 
259
259
  #### `message.recall`
260
260
 
@@ -360,29 +360,6 @@
360
360
  }
361
361
  ```
362
362
 
363
- #### `event/message.ack`
364
-
365
- 消息确认事件(通知发送方消息已被接收方确认)。
366
-
367
- ```json
368
- {
369
- "jsonrpc": "2.0",
370
- "method": "event/message.ack",
371
- "params": {
372
- "to": "bob.aid.pub",
373
- "device_id": "device-001",
374
- "slot_id": "slot-a",
375
- "ack_seq": 43,
376
- "timestamp": 1709712003
377
- }
378
- }
379
- ```
380
-
381
- - `to`:确认方 AID
382
- - `device_id`:触发 ack 的设备标识;legacy 客户端为空字符串
383
- - `slot_id`:触发 ack 的消费槽位;空字符串表示设备单实例或 legacy 路径
384
- - `ack_seq`:确认到的序列号(含该 seq 及之前的所有消息)
385
-
386
363
  #### `event/message.recalled`
387
364
 
388
365
  消息被撤回事件(通知接收方消息已被发送方撤回)。
@@ -23,6 +23,7 @@
23
23
 
24
24
  ### [AUNClient.Auth](#authnamespace-clientauth)
25
25
  - [create_aid()](#await-create_aidparams-dict---dict) - 注册新 AID
26
+ - [check_aid()](#await-check_aidparams-dict---dict) - 检查 AID 状态(本地完整性 + 远程注册)
26
27
  - [authenticate()](#await-authenticateparams-dict--none---dict) - 认证获取令牌
27
28
  - [sign_agent_md()](#await-sign_agent_mdcontent-str-aid-str--none---str) - 为 agent.md 生成尾部签名 **(已 deprecated,建议改用 `client.publish_agent_md`)**
28
29
  - [verify_agent_md()](#await-verify_agent_mdcontent-str-aid-str--none-cert_pem-str--none---dict) - 验证 agent.md 尾部签名 **(已 deprecated,建议改用 `client.fetch_agent_md`)**
@@ -552,6 +553,46 @@ result = await client.auth.create_aid({"aid": MY_AID})
552
553
 
553
554
  ---
554
555
 
556
+ ### `await check_aid(params: dict) -> dict`
557
+
558
+ 检查 AID 的本地密钥/证书完整性和远程注册状态。用于首次启动时判断是创建还是恢复,或连接前确认本地状态。
559
+
560
+ **参数**
561
+
562
+ | 字段 | 类型 | 必填 | 说明 |
563
+ |------|------|------|------|
564
+ | `aid` | `str` | 是 | 要检查的 AID |
565
+
566
+ **返回值**
567
+
568
+ | 字段 | 类型 | 说明 |
569
+ |------|------|------|
570
+ | `status` | `str` | `local_ready` / `local_incomplete` / `available` / `registered_remote` / `unknown` |
571
+ | `can_register` | `bool\|null` | 是否可注册(`local_ready` 时为 `false`) |
572
+ | `local` | `dict` | 本地状态详情(`exists` / `complete` / `private_key` / `public_key` / `certificate` / `issues`) |
573
+ | `remote` | `dict` | 远程状态(`status`: `not_checked` / `registered` / `available` / `error`) |
574
+
575
+ ```python
576
+ result = await client.auth.check_aid({"aid": "alice.agentid.pub"})
577
+ if result["status"] == "local_ready":
578
+ # 可以直接连接
579
+ pass
580
+ elif result["can_register"]:
581
+ # AID 可用,创建新身份
582
+ await client.auth.create_aid({"aid": "alice.agentid.pub"})
583
+ ```
584
+
585
+ **跨语言**
586
+
587
+ | 语言 | 调用方式 |
588
+ |------|----------|
589
+ | Python | `await client.auth.check_aid({"aid": "..."})` |
590
+ | TypeScript | `await client.auth.checkAid({ aid: '...' })` |
591
+ | Go | `client.Auth.CheckAID(ctx, map[string]any{"aid": "..."})` |
592
+ | C++ | `client->Auth()->CheckAID("...", callback)` |
593
+
594
+ ---
595
+
555
596
  ### `await authenticate(params: dict | None) -> dict`
556
597
 
557
598
  执行双向 ECDSA 挑战-响应认证,获取访问令牌。