@agentunion/fastaun 0.5.20 → 0.5.22

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 (128) hide show
  1. package/CHANGELOG.md +104 -0
  2. package/_packed_docs/CHANGELOG.md +104 -0
  3. package/_packed_docs/INDEX.md +59 -34
  4. package/_packed_docs/KITE_DOCS_GUIDE.md +59 -52
  5. package/_packed_docs/agent.md/working/AID/347/261/273/345/236/213-owner/345/205/263/347/263/273/344/270/216/346/215/242owner/347/274/226/346/216/222/346/226/271/346/241/210.md +530 -0
  6. package/_packed_docs/agent.md/working/AID/347/261/273/345/236/213-owner/345/205/263/347/263/273/345/256/214/346/225/264/350/256/276/350/256/241/344/270/216/345/256/236/346/226/275/350/256/241/345/210/222.md +685 -0
  7. package/_packed_docs/agent.md/working/agent.md-schema/344/270/216/347/255/276/345/217/221/351/252/214/347/255/276/346/265/201/347/250/213/346/276/204/346/270/205.md +349 -0
  8. package/_packed_docs/agent.md/working//346/234/254/345/234/260Docker/346/265/213/350/257/225Bug/346/270/205/345/215/225.md +40 -0
  9. 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 +307 -67
  10. package/_packed_docs/aun/346/265/213/350/257/225/350/277/220/350/241/214/346/214/207/345/215/227.md +41 -15
  11. package/_packed_docs/protocol/06-/346/234/215/345/212/241/345/215/217/350/256/256.md +1433 -1392
  12. package/_packed_docs/protocol/08-AUN-E2EE.md +17 -12
  13. package/_packed_docs/protocol/11-Storage-/345/255/220/345/215/217/350/256/256.md +30 -8
  14. package/_packed_docs/protocol/Ownership/345/215/217/350/256/256/345/256/232/344/271/211.md +2 -0
  15. package/_packed_docs/protocol/Ownership/345/215/217/350/256/256/345/256/232/344/271/2112.1.md +33 -22
  16. package/_packed_docs/sdk/0.5.21-SDK/345/272/224/347/224/250/351/233/206/346/210/220/346/214/207/345/215/227.md +368 -0
  17. package/_packed_docs/sdk/0.5.21-SDK/345/274/200/345/217/221/344/270/216/347/247/273/346/244/215/346/214/207/345/215/227.md +350 -0
  18. package/_packed_docs/sdk/0.5.22-SDK/345/272/224/347/224/250/351/233/206/346/210/220/346/214/207/345/215/227.md +212 -0
  19. package/_packed_docs/sdk/0.5.22-SDK/345/274/200/345/217/221/344/270/216/347/247/273/346/244/215/346/214/207/345/215/227.md +199 -0
  20. package/_packed_docs/sdk/01-/345/277/253/351/200/237/345/274/200/345/247/213.md +1 -1
  21. package/_packed_docs/sdk/02-WebSocket/345/215/217/350/256/256.md +5 -1
  22. package/_packed_docs/sdk/03-/346/240/270/345/277/203/346/246/202/345/277/265.md +64 -64
  23. package/_packed_docs/sdk/04-/350/277/236/346/216/245/344/270/216/350/256/244/350/257/201.md +4 -1
  24. package/_packed_docs/sdk/05-E2EE/345/212/240/345/257/206/351/200/232/344/277/241.md +42 -39
  25. package/_packed_docs/sdk/06-API/346/211/213/345/206/214.md +163 -14
  26. package/_packed_docs/sdk/08-/346/234/200/344/275/263/345/256/236/350/267/265.md +48 -47
  27. package/_packed_docs/sdk/09-group-rpc-manual.md +15 -2
  28. package/_packed_docs/sdk/09-message-rpc-manual.md +250 -160
  29. package/_packed_docs/sdk/09-storage-rpc-manual.md +64 -7
  30. package/_packed_docs/sdk/09-/345/207/255/350/257/201/346/234/215/345/212/241RPC/346/211/213/345/206/214.md +73 -0
  31. package/_packed_docs/sdk/09-/347/273/204/347/273/207/346/234/215/345/212/241RPC/346/211/213/345/206/214.md +90 -0
  32. package/_packed_docs/sdk/AUN_DOCS_GUIDE.md +33 -25
  33. package/_packed_docs/sdk/INDEX.md +67 -33
  34. package/_packed_docs/sdk/Ownership-SDK/347/274/226/346/216/222/346/214/207/345/215/2272.1.md +74 -57
  35. package/_packed_docs/sdk/Ownership2.1-SDK/345/272/224/347/224/250/351/233/206/346/210/220/346/214/207/345/215/227.md +312 -300
  36. package/_packed_docs/sdk/Ownership2.1-SDK/345/274/200/345/217/221/344/270/216/347/247/273/346/244/215/346/214/207/345/215/227.md +322 -382
  37. package/_packed_docs/sdk/Ownership2.1-TDD/345/210/206/351/230/266/346/256/265/345/256/236/346/226/275/350/256/241/345/210/222.md +708 -708
  38. package/_packed_docs/sdk/Ownership2.1/350/257/246/347/273/206/350/256/276/350/256/241.md +28 -20
  39. package/_packed_docs/sdk//345/207/255/350/257/201/344/270/216/347/273/204/347/273/207/346/234/215/345/212/241SDK/345/272/224/347/224/250/351/233/206/346/210/220/346/214/207/345/215/227.md +190 -97
  40. package/_packed_docs/sdk//345/207/255/350/257/201/344/270/216/347/273/204/347/273/207/346/234/215/345/212/241SDK/345/274/200/345/217/221/344/270/216/347/247/273/346/244/215/346/214/207/345/215/227.md +158 -127
  41. package/dist/agent-md-schema.js +6 -4
  42. package/dist/agent-md-schema.js.map +1 -1
  43. package/dist/agent-md.d.ts +22 -2
  44. package/dist/agent-md.js +92 -68
  45. package/dist/agent-md.js.map +1 -1
  46. package/dist/aid-store.d.ts +13 -0
  47. package/dist/aid-store.js +50 -15
  48. package/dist/aid-store.js.map +1 -1
  49. package/dist/auth.d.ts +1 -0
  50. package/dist/auth.js +22 -2
  51. package/dist/auth.js.map +1 -1
  52. package/dist/cert-utils.d.ts +1 -0
  53. package/dist/cert-utils.js +13 -0
  54. package/dist/cert-utils.js.map +1 -1
  55. package/dist/client/delivery.d.ts +87 -1
  56. package/dist/client/delivery.js +1387 -139
  57. package/dist/client/delivery.js.map +1 -1
  58. package/dist/client/group-state.js +3 -0
  59. package/dist/client/group-state.js.map +1 -1
  60. package/dist/client/rpc-pipeline.d.ts +4 -1
  61. package/dist/client/rpc-pipeline.js +149 -37
  62. package/dist/client/rpc-pipeline.js.map +1 -1
  63. package/dist/client/v2-e2ee.d.ts +12 -2
  64. package/dist/client/v2-e2ee.js +831 -304
  65. package/dist/client/v2-e2ee.js.map +1 -1
  66. package/dist/client.d.ts +26 -2
  67. package/dist/client.js +412 -68
  68. package/dist/client.js.map +1 -1
  69. package/dist/config.d.ts +4 -0
  70. package/dist/config.js +1 -0
  71. package/dist/config.js.map +1 -1
  72. package/dist/events.d.ts +18 -1
  73. package/dist/events.js +148 -9
  74. package/dist/events.js.map +1 -1
  75. package/dist/facades.d.ts +43 -1
  76. package/dist/facades.js +363 -7
  77. package/dist/facades.js.map +1 -1
  78. package/dist/group-fs.d.ts +1 -0
  79. package/dist/group-fs.js +37 -19
  80. package/dist/group-fs.js.map +1 -1
  81. package/dist/index.d.ts +5 -3
  82. package/dist/index.js +1 -1
  83. package/dist/index.js.map +1 -1
  84. package/dist/keystore/aid-db.d.ts +6 -1
  85. package/dist/keystore/aid-db.js +184 -42
  86. package/dist/keystore/aid-db.js.map +1 -1
  87. package/dist/keystore/index.d.ts +14 -0
  88. package/dist/keystore/local-token-store.d.ts +9 -1
  89. package/dist/keystore/local-token-store.js +79 -14
  90. package/dist/keystore/local-token-store.js.map +1 -1
  91. package/dist/org-protocol.d.ts +46 -0
  92. package/dist/org-protocol.js +802 -12
  93. package/dist/org-protocol.js.map +1 -1
  94. package/dist/ownership-v21.d.ts +36 -5
  95. package/dist/ownership-v21.js +168 -52
  96. package/dist/ownership-v21.js.map +1 -1
  97. package/dist/ownership-workflow.d.ts +24 -2
  98. package/dist/ownership-workflow.js +682 -41
  99. package/dist/ownership-workflow.js.map +1 -1
  100. package/dist/secret-store/file-store.js +84 -0
  101. package/dist/secret-store/file-store.js.map +1 -1
  102. package/dist/seq-tracker.d.ts +1 -0
  103. package/dist/seq-tracker.js +2 -2
  104. package/dist/seq-tracker.js.map +1 -1
  105. package/dist/storage/lowlevel.d.ts +6 -0
  106. package/dist/storage/lowlevel.js +24 -7
  107. package/dist/storage/lowlevel.js.map +1 -1
  108. package/dist/storage/read-cache.d.ts +70 -0
  109. package/dist/storage/read-cache.js +625 -0
  110. package/dist/storage/read-cache.js.map +1 -0
  111. package/dist/storage/vfs.d.ts +2 -0
  112. package/dist/storage/vfs.js +50 -15
  113. package/dist/storage/vfs.js.map +1 -1
  114. package/dist/tools/cross-sdk-agent.d.ts +86 -3
  115. package/dist/tools/cross-sdk-agent.js +758 -46
  116. package/dist/tools/cross-sdk-agent.js.map +1 -1
  117. package/dist/transport.d.ts +3 -0
  118. package/dist/transport.js +104 -46
  119. package/dist/transport.js.map +1 -1
  120. package/dist/types.d.ts +1 -0
  121. package/dist/v2/e2ee/encrypt-group.js +1 -0
  122. package/dist/v2/e2ee/encrypt-group.js.map +1 -1
  123. package/dist/v2/e2ee/encrypt-p2p.js +1 -0
  124. package/dist/v2/e2ee/encrypt-p2p.js.map +1 -1
  125. package/dist/v2/e2ee/types.d.ts +1 -0
  126. package/dist/version.d.ts +1 -1
  127. package/dist/version.js +1 -1
  128. package/package.json +1 -1
@@ -0,0 +1,350 @@
1
+ # AUN SDK 0.5.21 开发与移植指南
2
+
3
+ > 面向 SDK 维护者及其它语言 SDK 的实现者。依据当前 `0.5.21` 工作区,对照已发布 `0.5.20` 快照 `08221fbb`;当前版本仍标记未发布。
4
+ >
5
+ > 本文整理实现顺序、公开契约、提交边界与验收条件;应用调用另见 [应用集成指南](0.5.21-SDK应用集成指南.md)。TypeScript 仅作为接口和数据形状示例,语言差异不得改变 wire、签名字节或授权结论。
6
+
7
+ ## 1. 范围与规范依据
8
+
9
+ 本版需要对齐九个方面:peer 消费目录与按 sender 同步;batch、背压和交付提交;resolve 元数据及按需共识;普通 agent.md 兼容;Ownership reset 与旧任务;凭证续期和撤销;组织恢复;受保护 checkpoint;诊断和证书并发。
10
+
11
+ | 依据 | 用途 |
12
+ | --- | --- |
13
+ | `ts/CHANGELOG.md` 等四端 CHANGELOG | 相对发布基线的接口与行为摘要 |
14
+ | `python/CHANGES_FOR_PARITY.md` 的 v0.5.21 | 四端实现落点、语言边界和测试入口 |
15
+ | [API 手册](06-API手册.md) | 当前公开签名、resolve 完整输入输出与事件 |
16
+ | [Message RPC](09-message-rpc-manual.md)、[Group RPC](09-group-rpc-manual.md) | 目录、Pull/History/ACK、覆盖证明和批量交付契约 |
17
+ | [Ownership 协议 2.1](../protocol/Ownership协议定义2.1.md) | 当前双文件、六字段声明、签名和授权规则 |
18
+ | [凭证与组织移植指南](凭证与组织服务SDK开发与移植指南.md) | CAP、canonical JSON、请求绑定及组织生命周期基础 |
19
+
20
+ 历史文档中的旧版本实现记录不自动升级为 0.5.21 契约。`agent.md/SCHEMA.md` 是 legacy Ownership 2.0;普通主体的当前关系以 2.1 为准。凭证与组织专题保留 0.5.19 标题,本版新增的 current、续期、撤销及恢复在本指南补充。
21
+
22
+ ## 2. 实现分层与公开入口
23
+
24
+ | 层 | 实现职责 | 不应混入的职责 |
25
+ | --- | --- | --- |
26
+ | 身份存储 | AID 注册/加载、证书、密钥保护、名片草稿与 resolve | 普通名片读取不能强依赖 owner 关系可用 |
27
+ | 协议与密码学 | 严格解析、canonical bytes、签名、证书与证据验证 | 不能凭服务端布尔投影或 UI 状态授予权限 |
28
+ | 连接运行时 | 认证、能力协商、身份/设备/slot、连接代次、重连 | 旧代响应不能导入当前身份或推进其状态 |
29
+ | 同步与交付 | namespace、水位、Pull Gate、预取、应用事件、提交及 ACK | 网络成功不等同于应用成功;History 不进入实时提交 |
30
+ | 工作流与持久化 | Ownership、续期、组织创建/转让、checkpoint CAS 和恢复 | 不因重试而更换 operation、密钥、审批、原签名字节或条件 |
31
+ | Facade | 语言化命名、参数传递、RPC 映射和公开结果 | 不复制另一套密码学或状态机 |
32
+
33
+ ### 2.1 必须覆盖的新增入口
34
+
35
+ | 能力 | Python | TypeScript / 浏览器 | Go |
36
+ | --- | --- | --- | --- |
37
+ | 消息消费目录 | `message.peers` | `message.peers` | `MessageFacade.Peers` |
38
+ | batch 订阅 | `on` 异步处理器 | `on` 返回 Promise 的处理器 | `OnBatch(event, func(any) error)` |
39
+ | reset 本端未完成关系任务 | `reset_ownership_task()` | `resetOwnershipTask()` | `ResetOwnershipTask(ctx)` |
40
+ | 当前托管凭证 | `credential.current` | `credential.current` | `CredentialFacade.Current` |
41
+ | dry-run 诊断 | `debug.diag` | `debug.diag` | `DebugFacade.Diag` |
42
+ | resolve 共识选项 | `ownership/ownership_ttl_ms` | `ownership/ownershipTtlMs` | `Ownership/OwnershipTTL` |
43
+
44
+ 保留现有构造约束:AIDStore 管本地身份,AUNClient 接收可选 AID 对象。Node 的 load 同步,浏览器 load 异步;RPC 采用各语言的异步或 context/error 约定。不得把四端方法名、返回包装和同步性强行写成完全相同。
45
+
46
+ ## 3. peer 能力、目录与消费水位
47
+
48
+ ### 3.1 能力协商与状态隔离
49
+
50
+ 新客户端在 `auth.connect` 声明 `p2p_peer_pull_v1: true`;受认证连接响应必须以严格布尔 true 确认。不接受 `1`、`"true"`、缺字段或普通业务响应作为能力证据。未确认时按 `unsupported_protocol` 处理,不自行猜测支持或混用 global 消费路径。
51
+
52
+ P2P 状态至少按接收 AID、device、消费 slot 隔离键和完整 sender 分离。peer namespace 为 `p2p.peer.v1/` 加完整 sender UTF-8 的无 padding base64url;群消息、群事件沿用 `group:{id}`、`group_event:{id}`。
53
+
54
+ 除存储身份外,每次网络与应用工作还绑定连接代次及 namespace 代次。目录响应、页准备、每个处理器执行和提交前复核;身份、设备、slot 或连接变化后,不提交旧代结果。不能只在请求发出时检查一次。
55
+
56
+ ### 3.2 目录契约
57
+
58
+ | 条件 | 必须保留的语义 |
59
+ | --- | --- |
60
+ | `filter=pending` | 完整返回所有候选 peer,不分页;拒绝 limit/page_token,包含 volatile-only peer |
61
+ | `filter=all` | limit 为 1–200,使用 next_page_token 翻页;表示消息状态目录,不能代替联系人目录 |
62
+ | `catalog_ready=false` | 尚未完成目录准备,保留重试,不能发布成功空快照或判同步完成 |
63
+ | 响应绑定 | 校验 cursor_scope、receiver、device、sender 等对应请求和当前连接上下文 |
64
+ | `bootstrap_floor_seq` | 首次 peer 模式冻结的旧服务端 ACK;已有 peer ACK 优先,后来新 peer 仍使用固定基线 |
65
+ | `pending_count_estimate` | 可选整体持久跨度上界,不含 volatile;缺省不补 0,不用于调度、Tail 决策或完成判断 |
66
+
67
+ 目录不再返回逐 peer/整体三类精确 pending 数量;不要在移植端额外扫描 COUNT/SUM 模拟。目录 `next_pending_seq` 可以是当前 peer A,包括 0,是排序近似,不是首条未确认消息的精确位置。
68
+
69
+ 正常 Forward 页的可选 `next_pending_seq` 可提供更精确提示,只能在该页可靠 commit 后采用。缺失或非法提示不阻断合法页,也不能补造成 `covered_through_seq+1`。迟到提示不得回退已确认位置;ACK 失败保留独立待确认责任。
70
+
71
+ 内部调度使用副本,不重排 RPC 返回或 `message.peers_snapshot` 的应用列表。连续后台 peer Forward 段按有效提示稳定排序,缺提示回退已确认覆盖和本地 A;默认每 4 次实际派发给 FIFO 一次机会。前台优先和其它 namespace 边界保持,折叠 waiter 不计为实际派发。
72
+
73
+ ### 3.3 A/T/H、稀疏 seq 与 ACK
74
+
75
+ | 水位或证据 | 含义 |
76
+ | --- | --- |
77
+ | `A / ack` | 已提交的 Forward 前缀;只有它可用于 ACK,要求实际交付及有效覆盖证明 |
78
+ | `T / tail` | Tail 已扫描实时窗口的左边界 |
79
+ | `H / head` | Tail 已扫描实时窗口的右边界 |
80
+ | peer Pull proof | `scan_after_seq/covered_through_seq/next_after_seq/head_seq` 等,证明本次扫描覆盖 |
81
+ | `prev_peer_seq` | Push 与本地 peer 前缀衔接的前驱证明,不要求数字上相邻 |
82
+
83
+ 原 seq 仍来自接收设备共享收件箱,peer 之间天然稀疏。不得将缺少相邻数字当成丢消息,也不得用已扫描上界代替实际交付。合法 retention floor 可说明永久不可取前缀;未解密或处理器失败的消息不能被覆盖证明直接越过。
84
+
85
+ 只有已验证自身名片为 human 时自动先 Tail 再 Forward;未知或其它类型直接 Forward。新设备初始化、Push、后台目录刷新及重连恢复不能借用其它 sender 的进度。
86
+
87
+ peer ACK 不推进旧 global cursor,不修改其它 peer;运行中观察到的服务端 ACK 不能替代本地交付。持久 seq 和 volatile cursor 独立保存与确认,不能把临时消息位置写入持久 seq。
88
+
89
+ ### 3.4 公开 Pull/History 行为
90
+
91
+ - 指定 sender:处理该 peer 的 Pull、历史与 ACK,校验响应 sender 与设备上下文。
92
+ - 省略 sender 的 Pull:先取得完整 pending 目录,通过共享 Gate 调度各 peer,返回规范 `peers` 和 `partial`;显式 after_seq、volatile cursor、window_mode 或 force=true 必须指定 sender。
93
+ - History:只验证、解密并返回,不推进实时 A/T/H、不 ACK、不发布实时事件。
94
+ - History/force/Tail 的返回列表不按实时去重缓存删行;应用按消息 ID 合并展示。
95
+ - Group:保留原消息/群事件游标、成员可见性和终态规则,不能将 P2P peer 规则直接套用。
96
+
97
+ ## 4. Pull Gate、batch 与提交时序
98
+
99
+ ### 4.1 网络与应用队列
100
+
101
+ 每个 AUNClient 一个共享网络 Pull Gate:同 namespace 单飞,不同 namespace 最多 4 个网络请求并行;相同 key 折叠,可运行前台 FIFO 优先于后台工作。网络名额每页响应或错误后释放,本地解密、应用处理和后续 producer 不跨页占用该名额。
102
+
103
+ Pull 页容量为 200,最多预取 4 页。预取/解密准备可重叠,同 namespace 页交付保持顺序;应用消息队列按消息权重预留容量,默认共享上限为 `200 × 4 = 800`,不是每个 namespace 各 800,也不是 800 个任意大小批次。请求调小 limit 不改变内部容量。
104
+
105
+ 后台 max_pages 限定单个工作片,达到预算仍须保留并续调度持久/volatile 待拉责任。超时、取消、关闭和代次失效不能使旧任务与新任务同时提交同 namespace 状态。
106
+
107
+ ### 4.2 batch 载荷与订阅选择
108
+
109
+ 以下 TypeScript 类型用于描述载荷形状,不代表 SDK 新增了同名类型导出:
110
+
111
+ ```typescript
112
+ type DeliveryBatch = {
113
+ namespace: string;
114
+ items: Array<{ event: string; payload: unknown }>;
115
+ source: string;
116
+ };
117
+ ```
118
+
119
+ | batch | 原事件 |
120
+ | --- | --- |
121
+ | `message.batch` | message.received、message.recalled |
122
+ | `group.message_batch` | group.message_created、group.message_recalled |
123
+ | `group.event_batch` | group.changed |
124
+
125
+ 实际页开始时固定该类 batch 模式和 batch handlers。存在订阅则仅交付 batch,否则完整沿用原 single 链,single listeners 动态查找;没有 single 订阅也不跳过内部处理。不能双发,也不能失败后回落 single。
126
+
127
+ 批次不跨 namespace 或实际页,保留 items 顺序、原事件名、payload 和 source,不按 need_render 过滤;Push/inline 形成单元素批次,空 items 不发布。群内部成员、密钥、解散处理顺序不因外部 batch 改变。共享 FIFO 不承诺跨 peer 按全局 seq 排序。
128
+
129
+ ### 4.3 成功提交顺序
130
+
131
+ 1. 固定页上下文及处理器快照,预留应用容量,获取并验证原响应及覆盖证明。
132
+ 2. 验证/解密消息,按既有顺序执行协议内部处理,收集应用事件及延后提交动作。
133
+ 3. 发布 batch 或逐条事件,等待全部所需处理器完成;每个处理器执行前复核身份代次。
134
+ 4. 再检查页、namespace 和连接仍有效,完成运行时去重标记,并按该类型原路径可靠提交水位。
135
+ 5. 仅用已提交 A 提交或捎带 ACK;最终页单独确认最终累计 ACK,不为它额外发一次空 Pull。
136
+ 6. 核对服务端实际确认位置,响应丢失或 ACK 不足时保留原待确认责任。
137
+
138
+ ### 4.4 失败与重放
139
+
140
+ | 失败阶段 | 移植端要求 |
141
+ | --- | --- |
142
+ | 页权威性、sender 或 proof 不匹配 | 不交付、不推进该页水位,不借其它 peer 结果补齐 |
143
+ | 解密或准备未完成 | 不越过未交付消息;保留既有 sender IK/pending 恢复责任 |
144
+ | handler 抛错或 Promise/error 失败 | 不确认失败范围,不改为逐条重发;已发生的业务副作用可能被重放 |
145
+ | 水位持久化失败 | 不 ACK 未可靠提交位置,保留此前已合法提交的前缀 |
146
+ | 身份失效或取消 | 停止旧代处理与提交,不把旧结果写入新身份 |
147
+ | ACK 失败或响应丢失 | 保留已提交页与原确认责任,重查实际 ACK;不能重复创造业务完成证据 |
148
+
149
+ TS/浏览器处理器返回 Promise,Python dispatcher 等待异步处理器,Go 的 `OnBatch` 返回 error 可阻止成功提交;原 Go `On` 保留兼容。处理器内再等待同一应用交付链会导致重入,移植端应保持现有拒绝行为。
150
+
151
+ ### 4.5 去重不是业务事务
152
+
153
+ 当前 P2P 热路径使用最多 50,000 条运行时成功绑定记录。身份键包含接收 AID、device、slot、事件类别和原正 delivery seq,并验证 sender/message_id;不把来源、namespace 或 Push/Pull/Tail 作为新的投递身份。
154
+
155
+ 内存淘汰、重建 client、崩溃或版本切换允许重放;多个 client/进程不共享首次回调 claim。各端已有 receipt 存储接口,不表示当前热路径逐条读写它们,也不能把该扩展变成自定义 store 的新强制依赖。A/T/H 和 SDK receipt 都不能替代应用数据库中的持久幂等事务。volatile 与 Group 保持各自原去重边界。
156
+
157
+ ## 5. resolve 与 frontmatter 移植
158
+
159
+ ### 5.1 公开输入输出
160
+
161
+ 沿用 resolve,默认不查询 Ownership,不增加平行的元数据查询 API。TS/JS 的 `ResolveOpts` 为 `forceRefresh/skipAgentMd/timeout/ownership/ownershipTtlMs`;成功输出保留 `aid/agent_md/source`,按需增加 `ownership`。
162
+
163
+ ```typescript
164
+ import type { AIDStore, OwnershipConsensusChecker, ResolveOpts } from '@agentunion/fastaun';
165
+ declare const store: AIDStore;
166
+ declare const checker: OwnershipConsensusChecker;
167
+ const opts: ResolveOpts = { ownership: checker, ownershipTtlMs: 0 };
168
+ const resolved = await store.resolve('helper.agentid.pub', opts);
169
+ if (!resolved.ok) throw new Error(resolved.error.message);
170
+ ```
171
+
172
+ ownership 必须复用传入对象的共识入口,不能接受 true 后内部偷偷创建客户端。类型检查或语言接口适配不改变其现有身份、连接和超时配置。
173
+
174
+ ### 5.2 frontmatter 保真
175
+
176
+ `agent_md.content` 保留完整原文;`frontmatter` 保留同一原文解析后的全部键及嵌套类型,包括扩展字段。不得仅投影已知字段、统一转字符串或扁平化结构;返回对象与缓存对象隔离。
177
+
178
+ ```typescript
179
+ import type { AgentMdFrontmatter } from '@agentunion/fastaun';
180
+ const metadata: AgentMdFrontmatter = {
181
+ name: '示例', tags: ['sdk'],
182
+ 'x-settings': { enabled: true, max_parallel: 4, labels: ['a', 'b'] },
183
+ };
184
+ const extension: unknown = metadata['x-settings'];
185
+ ```
186
+
187
+ 标准字段在读取类型中可缺省,兼容旧名片;裸正文返回 `{}`,不补 Schema 默认值。新发布校验仍执行当前 aid/name/type/version、关系字段及实体指纹规则。独立 `downloadAgentMd` 返回同样的 frontmatter。
188
+
189
+ ### 5.3 共识结果与 owner.md 快照
190
+
191
+ 复用 `checkOwnershipConsensus` 等现有 2.1 核验,状态为 consensus/released/unbound/single_sided/invalid/unavailable/not_applicable;只有 consensus 的 owner_aid 非 null。保留原共识字段,再附 `checked_at`(Unix 毫秒)和 `cached`。
192
+
193
+ 实际读取 owner 文件后,可选 `owner_md` 保存 `owner_aid`、`bucket=default`、规范 path、exists、含签名完整 content、sha256、`observed_at`(Storage Unix 秒)。权威不存在返回 exists=false 和空内容/摘要;未读取时省略。文件快照存在不等于整体共识成功。
194
+
195
+ 身份或名片失败沿用外层 Result 失败;额外共识失败只形成 unavailable,不阻断已成功的身份/名片输出,不回退成过期 consensus。`skipAgentMd` 省略输出名片,但显式 ownership 仍可内部读取权威 agent.md。
196
+
197
+ ### 5.4 缓存与语言差异
198
+
199
+ 快照含 owner.md 原文,保存在 `agentmd.json.ownership_snapshot` 或浏览器 IndexedDB 等价记录,不新建独立 owner.md,不进入上传内容。默认 TTL 60 秒;目标相同、时钟未倒退、TTL 有效、状态不是 unavailable,且本次可比较的名片原文摘要相同时才复用。skip 输出无名片可比时按目标和 TTL 检查。
200
+
201
+ forceRefresh 或 TTL=0 绕过缓存。自有名片可来自本地草稿,共识始终检查远端原件;摘要不同不能让草稿中的 owner 变成有效授权。缓存仅服务查询展示,所有原有授权流程继续新鲜校验。
202
+
203
+ | 差异 | 必须保留 |
204
+ | --- | --- |
205
+ | Python opts | snake_case,兼容既有 camelCase 别名;ownership_ttl_ms 为毫秒 |
206
+ | Go opts | OwnershipTTL 为 `*time.Duration`;nil 默认一分钟,指向 0 表示不复用 |
207
+ | 超时 | TS/JS 名片默认 10 秒;Python 未传时名片默认 30 秒;Go 默认 10 秒 context 覆盖整个 Resolve |
208
+ | 返回结构 | Go 为 PascalCase,AgentMDInfo 没有 HTTP status;其它端保留既有 snake_case 数据字段 |
209
+ | 未取得材料 | Python 可为 None,TS/JS/Go 部分字段用空串或零值;先判断 status,不把占位值当权威观察 |
210
+
211
+ 完整字段以 [resolve 规格](06-API手册.md#resolve-输入与输出) 为准。
212
+
213
+ ## 6. 普通名片、签验与实体身份
214
+
215
+ 普通 agent.md 解析、读取、正文更新和普通 pending 恢复,不以前置共识、owner Storage 可用或关系状态为条件。正文更新原样保留已有 owner/ownership 及旧关系材料,使用本人签名和原 ETag/CAS;真正关系变更才进入对应 owner 授权校验。
216
+
217
+ 沿用单一通用签验核心:
218
+
219
+ - raw 输入显式区分 text/file,文件按原二进制处理;`file://` 文本不能被隐式当路径。
220
+ - document 每一签覆盖此前完整字节前缀;附签提供 signer_aid,按 AID、精确证书指纹和签署时间逐签校验。
221
+ - 连续尾签块总量限制、TAG、append/in-place 及 HTTP multi-v1 协商沿用原契约,不重排或重新序列化已签原文。
222
+ - 自有未发布草稿允许离线读取;失败稿由显式上传重试,下载、连接和重连不隐式重传。旧上传完成不能清除较新的草稿。
223
+ - 历史缺 Schema、旧指纹/CN 等兼容只用于原读取边界;新发布、现代实体及当前权威共识不能借历史兼容放宽验证。
224
+
225
+ Group/Org 由实体私钥主签,当前 owner 使用本人 token 上传,可选 owner 附签且全部签块验证。固定实体证书指纹、owner、完整多签原文与原 CAS;转移、rekey、解散后停止旧代 pending。普通实体名片显式重试与专属 create/transfer checkpoint 恢复分别维护。
226
+
227
+ 实体通用 Ownership 检查返回 not_applicable;不得为其新增普通 sub 声明或额外现代 V2 上传授权。细节见 [Ownership 移植指南](Ownership2.1-SDK开发与移植指南.md)。
228
+
229
+ ## 7. Ownership 工作流与历史兼容
230
+
231
+ ### 7.1 不变的协议面
232
+
233
+ 关系继续读取 sub 的 NS agent.md 和 owner Storage `default/sub_aids/{sub}/owner.md`。声明六字段为 `version/declaration_id/owner_aid/sub_aid/relation_version/declared_at`;`version=2`、声明 ID 为小写 UUIDv4,时间为 Unix 秒,沿用 `aun.ownership.sdk.v1` 控制格式,不增加独立关系资源或资源字段。
234
+
235
+ 权威读取核对 NS ETag、完整原文摘要和 owner 文件存在性,按原前后读取及 30 秒窗口验证当前证书与材料。owner.md 读取不依赖 Storage object_id/version;发布仍经同一 `create_upload_session → HTTP PUT → complete_upload`,使用原 expected_version 条件。不要将“读取不依赖对象版本”误读为“写入不需要 CAS”。
236
+
237
+ release 使用原声明版本 v;sub 清理后当前关系投影为 unbound/0,再绑定可从 1 开始。完整声明和文件材料识别关系,数字版本相同不能复用旧审批或授权。
238
+
239
+ ### 7.2 持久任务与完成证据
240
+
241
+ 先持久化 operation、参与方、明确审批、inbox/outbox、候选原签名字节和原提交条件,再执行对应副作用。任务存储 CAS/租约失败或损坏返回 persistence_unavailable,远端原件或条件冲突归 conflict,不混为可重建本地任务。
242
+
243
+ 恢复复用同一 operation、目标、审批、签名、授权期限和条件。目标已经提交时,须用本任务原件与新鲜共识精确匹配确认;P2P 发送成功、ACK、relation.confirmed 或本地阶段标记都不能单独完成任务。
244
+
245
+ 绑定/转移完成需新鲜目标 owner、版本和本任务材料匹配;释放完成须真实 released/v,或按原件严格关联的真实 unbound/0。历史 completed 保留,当前关系另行检查;通知或清理失败不能抹去已合法完成的历史。
246
+
247
+ ### 7.3 无参数 reset
248
+
249
+ `resetOwnershipTask()` 只归档当前 AID 发起的未完成 bind/release/transfer:原子保存原记录、revision 和摘要,再标记 reset,返回 `reset_operation_ids/skipped_operation_ids`。参与他人发起的任务和既有终态保留。
250
+
251
+ reset 后迟到消息、审批、旧 outbox 及指定 ID 恢复均不能复活原任务。不修改远端双文件、不解除锁、不自动创建新任务;无法确认可处理性的记录列入 skipped。不得把 reset 当成 IO、CAS 或远端关系冲突的通用修复。
252
+
253
+ ### 7.4 旧任务适配
254
+
255
+ | 原任务 | 当前恢复要求 |
256
+ | --- | --- |
257
+ | 0.5.20 无资源标记 | 沿原格式和控制消息继续,不能要求独立资源迁移 |
258
+ | 0.5.19 缺起始双文件快照 | 先核对完整历史和当前权威原件,在原 operation 下保存本地适配 checkpoint,保留有效审批和原签名 |
259
+ | 旧 Owner 候选尚未发布 | 原 expected_revision 须有权威证据精确匹配,不能以当前 version 替代;缺证据保留现场并返回 unavailable |
260
+ | 目标已提交、旧任务未完成 | 本地原始签名候选与新鲜双方共识精确匹配才观察完成,不能从当前网络补造历史原件或条件 |
261
+ | 0.5.19 release 的 wire target=base+1 | 保留原 wire 值,实际声明及 owner 文件仍按 base 验证 |
262
+ | 更早 proof/普通 pending | 保留原隔离读取和恢复边界,不自动伪造成 2.1 关系 |
263
+
264
+ 绑定优先恢复可继续的匹配任务。只有确认本地损坏或结构不可继续时,才归档后重新发起并重新审批;其它有效意图、网络/IO、CAS 竞争及远端冲突不能误判为垃圾任务。详细裁决见 [编排恢复章节](Ownership-SDK编排指南2.1.md#8-崩溃与响应丢失后的恢复)。
265
+
266
+ ## 8. 凭证、续期、撤销与组织恢复
267
+
268
+ ### 8.1 current 与自动续期
269
+
270
+ `credential.current(credentialOrCid)` 查询当前 AID 的托管记录,沿 successor CID 找到当前记录,返回隔离副本或 null;记录含 credential 及已有配套材料。它是本地 API,不能实现成不存在的 `credential.current` RPC,也不能把返回值视为新鲜服务端授权。
271
+
272
+ READY 后恢复托管长期凭证,在线期间每 60 秒扫描;断线、关闭、身份或连接变化取消原调度。每个异步步骤和保存前检查接收身份与代次,旧身份在途响应不能进入新身份。
273
+
274
+ 续期加密请求/响应保留原 CID、请求、双签/成员 binding、登记授权、回执及提交记录;先验证新 CAP、登记回执和当前成员状态,再提交本地 successor。不能仅因对端返回新 CID 就替换当前凭证,也不能重连时重复签发。
275
+
276
+ `aun-credential-renewal/1` 是当前实现的消息标识;定向实现和验证不等于已冻结跨版本续期 wire。既有显式 renewCredential 接口保持。
277
+
278
+ ### 8.2 撤销分页与完整 Verify
279
+
280
+ 撤销列表每页验签并绑定 authority、接收者、请求、游标和覆盖范围,先持久应用负向状态再推进已确认游标。坏页不推进 cursor,不能跳到后页掩盖缺失;已知撤销作用于当前凭证、父证明链及完整 Verify,旧输入不能绕过。
281
+
282
+ 完整 Verify 保留证书、有效期、受众、父链收窄、强 status proof、能力约束、实际 request binding、成员及代表关系检查。签名预检不能代替完整授权。父链 resolver 须建立 Credential 服务信任并核对实际查询绑定,不能信任自报 verified=true。
283
+
284
+ 协议 canonical JSON 对字符串做 NFC,外层 AUN client_signature 请求规则保持原字符串;不能混用两种摘要。CAP 等签名使用 P-256/SHA-256、DER 与严格标准 Base64,不能套用 V2 消息的 RAW 签名格式。通用/admission request binding 窗口不超过 300 秒;异步验证结束前重查可能过期的材料。
285
+
286
+ Credential/Org 业务调用走 service-plane。只有 revocationList 的 request binding 允许空 credential_cid;首次成员 admission 使用 membership_id 专用绑定,不能推广为空 CID 的普通业务例外。
287
+
288
+ ### 8.3 组织成员和实体恢复
289
+
290
+ 可信组织服务事件验证签名、当前成员包、接收 AID、身份和连接代次后才保存。本人 join/inviteAccept 仍需目标成员签名;代表证明只解决 actor 代表 target,不能替代该签名。成员更新固定原 membership 与版本,确认新 CAP 登记后才撤旧 CAP。
291
+
292
+ 组织创建/转让 checkpoint 保存固定 owner、组织 AID、实体密钥/证书、输入摘要、proposal、CAP、原请求与签名。自动生成 org ID 的路径同样持久化。存在 checkpoint 而密钥丢失时不能生成替代身份;转让必须按专属 rekey/finalize 流程继续。
293
+
294
+ 已发送续期跨期恢复仅按既有受限条件观察同一已提交结果:保留原 CID/request_id/nonce、原签名及版本 CAS,取得严格验签的新鲜状态,匹配完整 CAP 摘要与成员结果。不能通过刷新请求扩大授权、重 register 或重签;缺原有效回执时,issuer 的本地观察不能替代向 holder 交付的登记回执。完整条件见 [凭证与组织移植指南](凭证与组织服务SDK开发与移植指南.md)。
295
+
296
+ ## 9. 受保护 checkpoint 与存储迁移
297
+
298
+ 组织身份创建/转移、凭证续期等敏感 metadata 使用按 AID 和用途绑定的加密封装。读取兼容旧明文,后续写入升级;错误密钥、身份不匹配或损坏封装失败关闭,不能解释成“记录不存在”后重新创建。
299
+
300
+ 文件端 seed 轮换同时处理受保护 metadata,按原记录 CAS 写回并在失败时恢复已写记录。Python、Node TS、Go 实现该文件流程;浏览器使用自身 IndexedDB 与密钥存储机制,不声明具有相同文件 seed 迁移接口。
301
+
302
+ 迁移不能改变业务 operation、签名原文、审批和提交条件。SDK 存储恢复与应用消息数据库恢复分别验收;更换 seed 或 SDK 版本不能作为删除任务、重置水位或解除远端关系的理由。
303
+
304
+ ## 10. 诊断与并发证书获取
305
+
306
+ ### 10.1 diag 契约
307
+
308
+ scope 为空或 `*` 选全部,namespace 或 namespace.* 选命名空间,完整 RPC 精确匹配,debug 返回用法。先通过 `debug.diag` 获取目录,再逐项 dry-run,不调用业务处理器替代诊断。
309
+
310
+ 结果必须确认 `dry_run=true/executed=false`、目标 method 和有效阶段列表。不能因无异常、返回 truthy 或 HTTP 成功就计为 passed。缺真实证书/业务材料计 skipped 并说明原因;失败保留结构化 data/stage 与退出状态。
311
+
312
+ 公开报告包含 scope、aid、passed/failed/skipped、checks;分项包含 method、可选 scenario、status、duration_ms 及可选 result/error/data/reason/stage。诊断不改变业务完成状态,也不能把 skipped 计成通过。
313
+
314
+ ### 10.2 证书 single-flight
315
+
316
+ 只合并相同条件的在途请求,键保持 AID、精确指纹、签署时间、验证用途及超时策略等隔离;不能将历史签名读取与当前权威证书检查混用。失败移除 in-flight 记录,后续可重试,不能缓存为永久成功或永久失败。
317
+
318
+ 关闭时按语言生命周期收回工作:Go 取消并等待证书工作,Python 收回在途任务;TS/浏览器仍须阻止失效代次结果写回。并发合并不能放宽链、CRL/OCSP、指纹或当前有效性验证。
319
+
320
+ ## 11. 四端差异与代码定位
321
+
322
+ | SDK | 必须保留的语言边界 | 主要实现入口 |
323
+ | --- | --- | --- |
324
+ | Node TypeScript | Promise 处理器;低层 V2 `needRender`,RPC/收发结果 `need_render`;文件 seed 轮换 | `ts/src/client/{delivery,rpc-pipeline,v2-e2ee}.ts`、`events.ts`、`aid-store.ts`、`org-protocol.ts`、`keystore/local-token-store.ts` |
325
+ | 浏览器 JavaScript | WebCrypto/IndexedDB 异步,按身份与连接代次保护提交;浏览器包也有 TypeScript 类型 | `js/src/client/`、`events.ts`、`aid-store.ts`、`org-protocol.ts`、`keystore/indexeddb-token-store.ts` |
326
+ | Python | async RPC/dispatcher;本地协议 helper 保留同步约定;CLI diag/listen/org 的退出码及结构化输出 | `python/src/aun_core/_client/`、`aid_store.py`、`org_facades.py`、`ownership_workflow.py`、`keystore/` |
327
+ | Go | context/error、OnBatch 错误阻止提交;Resolve 返回 PascalCase 和 duration | `go/client_peers.go`、`client_delivery.go`、`facades.go`、`org_facades.go`、`aid_store.go`、`keystore/` |
328
+
329
+ TS/浏览器 Ownership 对应 `ownership-workflow.ts`、`ownership-v21.ts`;Python/Go 使用各自下划线文件名。对外 runtime version 和 V2 envelope 的 sdk_version 应与本端 0.5.21 产物一致。
330
+
331
+ 跨设备已读的公共顺序与设备 seq 在 TS/JS 超安全整数时保留精确十进制字符串,null 映射原样保留;不得复用浮点解析后的值签名、比较或提交。详细语言契约见 [已读状态移植指南](../跨设备已读未读SDK实现移植指南.md)。
332
+
333
+ ## 12. 移植与验收顺序
334
+
335
+ 按“协议向量 → 本地持久化 → RPC transcript → 交付故障 → 真实联网”推进,每个阶段先验证失败边界,再接入下一阶段。
336
+
337
+ | 阶段 | 必须证明的结果 | 现有入口 |
338
+ | --- | --- | --- |
339
+ | 1. 签验与公开模型 | canonical bytes、完整文件、多签、CAP/proof 向量一致;frontmatter 类型和历史缺省保持 | `tests/vectors/ownership_v21/vectors.json`、`tests/vectors/org-0.8/protocol.json`;四端 aid-store/agent-md/org-protocol 测试 |
340
+ | 2. peer 与水位 | 严格协商、固定 bootstrap、sender 隔离、稀疏覆盖、Tail/Forward、volatile 和旧代丢弃 | TS/JS `tests/unit/message-windows.test.ts`,Python `tests/unit/test_message_windows.py`,Go `client_identity_peers_test.go`、`forward_commit_test.go` |
341
+ | 3. batch 与失败提交 | 单/批互斥、页快照、消息权重背压;handler/存储/取消失败不提前 ACK;重放保持业务可幂等 | 四端 events/client/forward_commit;TS/JS `tests/unit/events.test.ts`,Go `events_test.go` |
342
+ | 4. resolve | 默认不查共识、全类型元数据、TTL/强刷/摘要失效、owner.md 原文、unavailable 隔离及返回副本 | 四端 aid-store、client-agent-md-api、ownership-v21/workflow 测试 |
343
+ | 5. Ownership 恢复 | 双文件/原 CAS、旧任务字节和审批保留、release 旧 wire、reset 不复活且远端不变 | 四端 ownership workflow/v21 与任务存储;共同 Ownership 向量 |
344
+ | 6. 凭证与组织 | current successor、坏撤销页不推进、旧 CAP 不绕撤销、登记确认、旧身份隔离、实体 checkpoint/rekey | 四端 org facade/protocol、keystore、seed migration 测试 |
345
+ | 7. 诊断与证书 | dry-run/executed/stage 严格核对;缺材料 skipped;并发键隔离、失败重试及关闭取消 | 四端 facade/client/auth,Python CLI diag/org 测试 |
346
+ | 8. 部署与互操作 | 同版/旧版真实包、四端互发、浏览器重载、单域及双域恢复 | `tests/cross-sdk/runner`、各端 cross-sdk agent,仓库测试运行指南 |
347
+
348
+ 至少注入这些故障:应用事务成功而 ACK 丢失、部分 batch handlers 成功、同页取消、切身份后旧响应、已有任务但密钥缺失、旧 revision 无权威证据、登记回执或撤销页损坏、seed 迁移中断、诊断缺 dry-run 确认。验收应说明哪些结果来自单元/向量、哪些来自真实服务及实际旧发布包。
349
+
350
+ 本指南不把存在测试用例、单次类型检查或历史通过计数当作 0.5.21 的全量发布结论。具体运行环境和联网步骤见 `docs/aun测试运行指南.md`、`docs/aun分布式测试运行指南.md`;本版差异清单见 `python/CHANGES_FOR_PARITY.md`。
@@ -0,0 +1,212 @@
1
+ # AUN SDK 0.5.22 应用集成指南
2
+
3
+ 面向应用开发者,基于 0.5.21。本文对应 2026-10-23 的未发布源码,示例使用 TypeScript。消息持久化、batch 交付与 peer 同步沿用 [0.5.21 应用集成指南](0.5.21-SDK应用集成指南.md);SDK 实现见 [0.5.22 移植指南](0.5.22-SDK开发与移植指南.md)。
4
+
5
+ ## 1. 本版应用需要关注的变化
6
+
7
+ | 领域 | 应用需要处理的变化 |
8
+ | --- | --- |
9
+ | 消息/群 | 后台失败退避,群终态停止补拉;非 active 群跳过自动恢复和提案确认,权限以当前查询为准 |
10
+ | Ownership | 接入两种绑定顺序、用户审批和任务恢复,以 fresh 共识确认当前关系 |
11
+ | Credential/Org | SDK 合并撤销推送并每小时补拉;应用使用当前完整成员包,保留原任务、请求和候选密钥 |
12
+ | 文件读取 | 元数据和符合条件的 inline 正文默认缓存 60 秒;需立即观察变化时强制刷新 |
13
+
14
+ ## 2. 身份、存储与连接
15
+
16
+ Node.js `>=22.16.0` 使用 `@agentunion/fastaun`,浏览器使用 `@agentunion/fastaun-browser`。升级保留原 `aunPath`、解密配置、设备/slot、任务及续期 checkpoint;应用消息仍存业务数据库。
17
+
18
+ 加载已注册身份,`AUN_PATH`、`AUN_SEED` 由部署提供:
19
+
20
+ ```typescript
21
+ import { AIDStore, AUNClient } from '@agentunion/fastaun';
22
+ const store = new AIDStore({
23
+ aunPath: process.env.AUN_PATH!, encryptionSeed: process.env.AUN_SEED ?? '',
24
+ slotId: 'main', verifySsl: true,
25
+ });
26
+ const loaded = store.load('helper.agentid.pub');
27
+ if (!loaded.ok) throw new Error(loaded.error.message);
28
+ if (!loaded.data.aid.isPrivateKeyValid()) throw new Error('本身份私钥不可用');
29
+ const client = new AUNClient(loaded.data.aid);
30
+ ```
31
+
32
+ `AUNClient` 接收 AID 对象,连接配置传给 `connect()`。可信根与 TLS 见 [连接与认证](04-连接与认证.md)。首次注册用 `store.register()`;owner 可省略,携带时仅保存待审批意图,不表示绑定完成,不重复申请。
33
+
34
+ 浏览器 `store.load()` 需 `await`,身份与缓存使用 IndexedDB,`aunPath` 为本地命名空间;示例见 [浏览器差异](0.5.21-SDK应用集成指南.md#23-浏览器差异)。
35
+
36
+ ## 3. 消息订阅与同步状态
37
+
38
+ 连接前注册处理器:`saveIncomingMessage` 完成约定的持久处理后返回;`showOwnershipRequest` 展示审批后返回,不等待用户点击。
39
+
40
+ ```typescript
41
+ import type { EventHandler } from '@agentunion/fastaun';
42
+ declare const saveIncomingMessage: EventHandler;
43
+ declare const showOwnershipRequest: EventHandler;
44
+ client.on('message.received', saveIncomingMessage);
45
+ client.on('ownership.request', showOwnershipRequest);
46
+ await client.connect({ auto_reconnect: true });
47
+ ```
48
+
49
+ 已有 `message.batch`/`message.recalled` 处理器时复用;不注册丢弃消息的空回调。仅订阅 `ownership.*` 不启动 P2P 后台收取。READY 后补订阅也会恢复积压,仍受 `background_sync`、背压、退避及连接代际约束。Ownership 控制消息由 SDK 内部验签、持久消费。
50
+
51
+ `connect()` 返回不表示同步和业务恢复完成。分别显示连接、同步与任务状态;保持原有提交后 ACK 和业务已读契约。
52
+
53
+ 非成员、封禁、群不存在或已解散等终态错误会停止该群消息和事件同步,保留本地消息;用户手动拉取成功或连接换代后恢复,无需应用高频轮询。
54
+
55
+ ## 4. Ownership 2.1 审批与恢复
56
+
57
+ ### 4.1 公有入口
58
+
59
+ | 角色或动作 | TypeScript 方法 |
60
+ | --- | --- |
61
+ | sub 向 owner 申请绑定 | `client.bindOwneraid(ownerAid)` |
62
+ | owner 邀请 sub 绑定 | `client.bindSubaid(subAid)` |
63
+ | 本端用户明确同意/拒绝 | `client.acceptOwnershipRequest(operationId)`/`client.rejectOwnershipRequest(operationId, reason)` |
64
+ | 当前 owner 释放 sub | `client.releaseSubaid(subAid)` |
65
+ | 当前 owner 发起三方转移 | `client.transferSubaid(subAid, newOwnerAid)` |
66
+ | 检查当前关系 | `client.checkOwnershipConsensus(subAid)` |
67
+
68
+ sub-first 申请:
69
+
70
+ ```typescript
71
+ const task = await client.bindOwneraid('owner.agentid.pub');
72
+ console.log(task.operation_id, task.status);
73
+ ```
74
+
75
+ 保存 `operation_id`,订阅 `ownership.action_required/progress/completed/rejected/stopped/error`。`ownership.request` 展示已验证请求,有权用户明确决定后才调用同意/拒绝。事件载荷无 `event.data` 包装;字段见 [Ownership 应用指南](Ownership2.1-SDK应用集成指南.md#3-ec-cli-集成示例sub-发起human-owner-同意)。
76
+
77
+ ### 4.2 两种绑定顺序
78
+
79
+ | 发起方 | SDK 编排 | 应用应观察的结果 |
80
+ | --- | --- | --- |
81
+ | sub-first | fresh 确认无锁及 Stage 能力 → 暂存 sub 的 `agent.md` → owner 同意并发布本轮 `owner.md` → NS fresh 验收 | 暂存为 `single_sided`,不授权;验收时 sub 可离线,无须再次上传 |
82
+ | owner-first | fresh 确认无锁 → owner 条件发布 `owner.md` 并发请求 → sub 验签、同意后直接条件提交 `agent.md` | 不用 Stage,无 bind.accept/owner.ready 往返;以 fresh 共识确认成立 |
83
+
84
+ 服务端须支持 2.1 fresh 检查和条件发布;sub-first 还须通过 Stage 能力预检,`Protocol: 2.1` 不能替代该检查。
85
+
86
+ 拒绝清理由 SDK 按原件和 CAS 条件执行:sub-first 清理本轮未锁定候选;owner-first 的 sub 不上传名片,owner 条件删除匹配的未锁邀请。应用不手动删文件或替换提交条件。
87
+
88
+ `ownership.completed` 表示任务目标曾核验完成;展示当前关系仍须查询,不能凭 pending、ACK 或用户同意授权:
89
+
90
+ ```typescript
91
+ const relation = await client.checkOwnershipConsensus('helper.agentid.pub');
92
+ console.log(relation.status, relation.owner_aid);
93
+ ```
94
+
95
+ 仅 `consensus` 且参与方匹配时确认绑定。`single_sided/released/unbound/invalid/unavailable` 分别为准备中、已释放、未绑定、材料无效、暂不可确认;Group/Org 使用专属生命周期,返回 `not_applicable`。
96
+
97
+ ### 4.3 重连、冲突与 reset
98
+
99
+ 恢复原任务及其审批、签名字节、请求参数、摘要和提交条件。共识冲突时 SDK 额外 fresh 重查一次;仍不一致返回可重试 `unavailable`,应用保留现场。
100
+
101
+ 本地 revision 冲突、NS HTTP 412、Storage `-32009` 是三类 CAS 冲突;按当前事实恢复,不能换新 ETag/对象版本重试旧原件。`persistence_unavailable` 须先恢复原存储。
102
+
103
+ `resetOwnershipTask()` 仅归档本端发起的未完成任务,不解绑、不解锁、不删远端文件。须用户明确要求,新申请重新审批;启动、断网或写入结果不明时不 reset。详见 [CAS 恢复边界](Ownership2.1-SDK开发与移植指南.md#103-cas-冲突分类与恢复边界)。
104
+
105
+ ## 5. resolve:frontmatter 与 owner 展示
106
+
107
+ `AIDStore.resolve()` 返回完整原文 `agent_md.content` 和保留 YAML 嵌套类型的 `agent_md.frontmatter`;扩展字段使用前按应用约定收窄类型。
108
+
109
+ ```typescript
110
+ const profile = await store.resolve('alice.agentid.pub', { ownership: client });
111
+ if (!profile.ok) throw new Error(profile.error.message);
112
+ console.log(profile.data.agent_md?.frontmatter);
113
+ console.log(profile.data.ownership?.status, profile.data.ownership?.cached);
114
+ ```
115
+
116
+ | opts | 默认值 | 用途 |
117
+ | --- | --- | --- |
118
+ | `ownership` | 不传 | 传已有 client,复用共识检查 |
119
+ | `ownershipTtlMs` | 60,000 ms | 关系展示快照 TTL;`0` 每次查询 |
120
+ | `forceRefresh` | `false` | 刷新身份/名片及已请求的关系快照 |
121
+ | `skipAgentMd` | `false` | 省略名片输出;共识仍可内部读取权威材料 |
122
+ | `timeout` | 10,000 ms | 名片下载超时;共识沿用 client 配置 |
123
+
124
+ 成功 `data` 含 `aid`、可选 `agent_md/ownership` 和 `source`。ownership 可含 `owner_md` 原文、摘要及观测信息,随展示快照保存,不另存本地 owner.md。额外共识不可用时,外层仍可成功,关系为 `unavailable`。
125
+
126
+ 展示快照独立于文件缓存,不能用于授权。自有身份可能返回未发布草稿,须核对 `source`;名片更新保留关系字段、本人签名和原 CAS。完整契约见 [resolve 输入与输出](06-API手册.md#resolve-输入与输出)。
127
+
128
+ ## 6. Storage / Group FS 默认读缓存
129
+
130
+ ### 6.1 缓存策略
131
+
132
+ | 响应或调用条件 | 行为 |
133
+ | --- | --- |
134
+ | 缺少 `read_cache`,或为 `null` | 元数据默认 60 秒;实际 ≤65,536 字节且 SHA-256 校验通过的完整正文默认缓存 |
135
+ | 显式 `reusable: true` | 正文另须 `inline: true`;省略 `max_age_ms` 默认 60 秒,有限正数最多 60 秒 |
136
+ | 显式禁止或无效策略 | `reusable: false`、空策略、显式 null/非正数/非法 TTL 不复用 |
137
+ | 单次 `noCache: true` | 强制回源校验,可条件复用正文;结果仍按策略更新缓存,不是 no-store |
138
+ | `consistency: 'authoritative'` | 支持该参数的底层 RPC 完全旁路读缓存并读取权威事实 |
139
+
140
+ `read_cache` 是服务端响应策略,特定文件由服务端显式禁用缓存;应用用刷新选项控制单次调用。热命中和重启不续期,远端更新/撤权可能到刷新或 TTL 到期才被观察。
141
+
142
+ ### 6.2 普通读取与强制刷新
143
+
144
+ ```typescript
145
+ const path = 'owner.agentid.pub:/sub_aids/helper.agentid.pub/owner.md';
146
+ const bytes = await client.storage.readBytes(path);
147
+ const refreshed = await client.storage.readBytes(path, { noCache: true });
148
+ const stat = await client.storage.stat(path, { noCache: true });
149
+ ```
150
+
151
+ 普通 `owner.md` 读取默认缓存;Ownership 管理和 fresh 共识由关系门面读取权威原件。
152
+
153
+ 刷新可发送 `if_sha256`;`not_modified` 仅复用摘要匹配的已验证完整正文,无正文不能返回空文件。详细校验见 [Storage 缓存](09-storage-rpc-manual.md#sdk-默认读缓存)。
154
+
155
+ ### 6.3 Group FS 与使用边界
156
+
157
+ Group FS 使用同一策略,TS/JS 支持 `noCache: true` 并兼容 `no_cache`;类型化 Storage VFS 使用 `noCache`。刷新选项由 SDK 消费,不传为服务端业务字段;入口见 [Group FS](09-group-rpc-manual.md#sdk-默认读缓存)。
158
+
159
+ 范围读取、显式预签及大正文保留原下载路径。`storage.list_share_links/check_access/list_tokens` 始终回源且不使其它缓存失效;写删、移动、相关权限变更会失效。缓存按身份、网关与业务参数隔离。
160
+
161
+ 有限次授权的 inline 读取仅返回正文时计次;本地命中、HEAD、无正文 `not_modified` 不计次。大对象按下载授权计次。联网仍检查撤销、过期、身份及权限。
162
+
163
+ Node.js/Python/Go 使用 SQLite 索引与摘要正文,浏览器用 IndexedDB;默认内存/持久正文预算为 32/256 MiB。缓存会淘汰,不能替代身份、任务和应用数据库的持久存储。
164
+
165
+ ## 7. 凭证与组织服务
166
+
167
+ ### 7.1 撤销推送与小时补拉
168
+
169
+ SDK 验证并持久合并 `credential.revoked`、`credential.revocationList`,防止乱序覆盖和分页回退。连接一小时后首次补拉,此后每小时一次,重连重新计时;凭证续期仍每分钟检查。
170
+
171
+ 撤销快照存于 keystore/tokenstore 的 `credential_revocations_v1` metadata(浏览器为 IndexedDB),不是 JSONL 事件流水。缺少 CID 不表示有效,仍须完整凭证及父证明链验证;PKI CRL/OCSP 是另一套缓存。
172
+
173
+ ### 7.2 使用当前完整成员包
174
+
175
+ ```typescript
176
+ declare const originalCredentialCid: string;
177
+ const current = await client.credential.current(originalCredentialCid);
178
+ if (!current) throw new Error('没有当前托管凭证');
179
+ const credential = current.credential;
180
+ const membershipBinding = current.membership_binding;
181
+ ```
182
+
183
+ `credential.current()` 沿本地续期链查询当前记录。续期响应立即保存 credential、membership binding、terms、registrationReceipt、服务端版本及权威信息,不等成员事件。业务请求通过 request binding helper 使用当前完整包,不长期复用最初的 CAP。
184
+
185
+ `long_term=false` 不自动续期;续期仅更新当前成员账户。
186
+
187
+ ### 7.3 组织创建、转让及服务部署
188
+
189
+ | 场景 | 应用处理 |
190
+ | --- | --- |
191
+ | 创建补偿冲突 | `CREDENTIAL_IDEMPOTENCY_KEY_REUSE` 保留任务和原请求,核对冲突,不换 ID 自动重试 |
192
+ | Python 候选私钥丢失 | `persistence_unavailable`:恢复原私钥,不生成替代密钥继续原请求 |
193
+ | Go 证书指纹不匹配 | 保留原身份和材料,核对 CA 返回的实体证书指纹 |
194
+ | TS/JS 转让已完成 | 同 transfer ID、owner、原参数可重放结果;重连跳过 completed |
195
+ | 跨域实体名片重试 | TS/JS/Go 使用上传者所属域 token,访问实体所在域;保留原 CAS |
196
+
197
+ 配套服务须部署撤销幂等恢复、创建补偿冲突保护、换钥代际/DER 修复、成员包与定向通知原子保存,见 [服务部署要求](0.5.22-SDK开发与移植指南.md#55-配套-credential--org-服务修复)。应用以验证结果和当前查询恢复状态,不依赖通知及时到达。
198
+
199
+ 业务参数与审批见 [凭证与组织应用指南](凭证与组织服务SDK应用集成指南.md)。
200
+
201
+ ## 8. 升级与应用验收
202
+
203
+ | 顺序 | 验收内容 |
204
+ | --- | --- |
205
+ | 构建与部署 | SDK 产物、Gateway peer、NS 2.1/Stage、Storage 条件发布及 Credential/Org 服务版本匹配 |
206
+ | 持久恢复 | 原身份、设备/slot、任务、续期 checkpoint 和业务数据库可恢复 |
207
+ | 消息 | 连接前/后订阅、断线、背压、提交后 ACK、群终态停止与手动恢复 |
208
+ | Ownership | 两种顺序、缺 Stage、拒绝清理、sub 离线、原件变化及响应丢失;pending 不授权,reset 不解锁 |
209
+ | 缓存 | 缺省/显式策略、64 KiB 边界、刷新与条件复用、失效、重启不续期;普通/权威 owner.md 分别验证 |
210
+ | 凭证组织 | 小时补拉、完整续期包、短期不续期、原密钥恢复、完成重放及补偿冲突 |
211
+
212
+ 测试入口见 [移植验收](0.5.22-SDK开发与移植指南.md#8-移植与验收顺序),实际验证范围见 [parity](../../python/CHANGES_FOR_PARITY.md#v0522--相对于-v0521-发布基线的变更未发布)。关闭前完成应用持久处理,再调用 `client.close()`。