@agentunion/fastaun-browser 0.5.20 → 0.5.21

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 (130) hide show
  1. package/CHANGELOG.md +47 -0
  2. package/_packed_docs/CHANGELOG.md +47 -0
  3. package/_packed_docs/INDEX.md +453 -440
  4. package/_packed_docs/KITE_DOCS_GUIDE.md +164 -161
  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/protocol/06-/346/234/215/345/212/241/345/215/217/350/256/256.md +1433 -1392
  10. package/_packed_docs/protocol/08-AUN-E2EE.md +17 -12
  11. package/_packed_docs/protocol/Ownership/345/215/217/350/256/256/345/256/232/344/271/211.md +2 -0
  12. package/_packed_docs/protocol/Ownership/345/215/217/350/256/256/345/256/232/344/271/2112.1.md +666 -658
  13. 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
  14. 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
  15. package/_packed_docs/sdk/01-/345/277/253/351/200/237/345/274/200/345/247/213.md +1 -1
  16. package/_packed_docs/sdk/02-WebSocket/345/215/217/350/256/256.md +5 -1
  17. package/_packed_docs/sdk/03-/346/240/270/345/277/203/346/246/202/345/277/265.md +64 -64
  18. package/_packed_docs/sdk/04-/350/277/236/346/216/245/344/270/216/350/256/244/350/257/201.md +4 -1
  19. package/_packed_docs/sdk/05-E2EE/345/212/240/345/257/206/351/200/232/344/277/241.md +42 -39
  20. package/_packed_docs/sdk/06-API/346/211/213/345/206/214.md +147 -14
  21. package/_packed_docs/sdk/08-/346/234/200/344/275/263/345/256/236/350/267/265.md +48 -47
  22. package/_packed_docs/sdk/09-group-rpc-manual.md +5 -2
  23. package/_packed_docs/sdk/09-message-rpc-manual.md +250 -160
  24. package/_packed_docs/sdk/09-/345/207/255/350/257/201/346/234/215/345/212/241RPC/346/211/213/345/206/214.md +71 -0
  25. package/_packed_docs/sdk/09-/347/273/204/347/273/207/346/234/215/345/212/241RPC/346/211/213/345/206/214.md +88 -0
  26. package/_packed_docs/sdk/AUN_DOCS_GUIDE.md +134 -130
  27. package/_packed_docs/sdk/INDEX.md +239 -221
  28. package/_packed_docs/sdk/Ownership-SDK/347/274/226/346/216/222/346/214/207/345/215/2272.1.md +930 -922
  29. 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 +106 -43
  30. 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 +180 -9
  31. 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
  32. package/_packed_docs/sdk/Ownership2.1/350/257/246/347/273/206/350/256/276/350/256/241.md +480 -476
  33. 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 +1 -1
  34. 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 +2 -2
  35. package/dist/agent-md-schema.d.ts +1 -0
  36. package/dist/agent-md-schema.d.ts.map +1 -1
  37. package/dist/agent-md-schema.js +5 -4
  38. package/dist/agent-md-schema.js.map +1 -1
  39. package/dist/agent-md.d.ts +25 -1
  40. package/dist/agent-md.d.ts.map +1 -1
  41. package/dist/agent-md.js +148 -71
  42. package/dist/agent-md.js.map +1 -1
  43. package/dist/aid-store.d.ts +13 -0
  44. package/dist/aid-store.d.ts.map +1 -1
  45. package/dist/aid-store.js +55 -8
  46. package/dist/aid-store.js.map +1 -1
  47. package/dist/aid.d.ts.map +1 -1
  48. package/dist/aid.js +2 -1
  49. package/dist/aid.js.map +1 -1
  50. package/dist/auth.d.ts.map +1 -1
  51. package/dist/auth.js +4 -0
  52. package/dist/auth.js.map +1 -1
  53. package/dist/bundle.js +4981 -1219
  54. package/dist/cert-utils.d.ts +1 -0
  55. package/dist/cert-utils.d.ts.map +1 -1
  56. package/dist/cert-utils.js +21 -0
  57. package/dist/cert-utils.js.map +1 -1
  58. package/dist/client/delivery.d.ts +101 -16
  59. package/dist/client/delivery.d.ts.map +1 -1
  60. package/dist/client/delivery.js +1172 -160
  61. package/dist/client/delivery.js.map +1 -1
  62. package/dist/client/rpc-pipeline.d.ts +4 -1
  63. package/dist/client/rpc-pipeline.d.ts.map +1 -1
  64. package/dist/client/rpc-pipeline.js +122 -48
  65. package/dist/client/rpc-pipeline.js.map +1 -1
  66. package/dist/client/v2-e2ee.d.ts +22 -3
  67. package/dist/client/v2-e2ee.d.ts.map +1 -1
  68. package/dist/client/v2-e2ee.js +1258 -649
  69. package/dist/client/v2-e2ee.js.map +1 -1
  70. package/dist/client.d.ts +23 -2
  71. package/dist/client.d.ts.map +1 -1
  72. package/dist/client.js +391 -87
  73. package/dist/client.js.map +1 -1
  74. package/dist/config.d.ts +4 -0
  75. package/dist/config.d.ts.map +1 -1
  76. package/dist/config.js +1 -0
  77. package/dist/config.js.map +1 -1
  78. package/dist/events.d.ts +19 -1
  79. package/dist/events.d.ts.map +1 -1
  80. package/dist/events.js +146 -23
  81. package/dist/events.js.map +1 -1
  82. package/dist/facades.d.ts +42 -1
  83. package/dist/facades.d.ts.map +1 -1
  84. package/dist/facades.js +363 -7
  85. package/dist/facades.js.map +1 -1
  86. package/dist/index.d.ts +5 -3
  87. package/dist/index.d.ts.map +1 -1
  88. package/dist/index.js +1 -1
  89. package/dist/index.js.map +1 -1
  90. package/dist/keystore/index.d.ts +14 -1
  91. package/dist/keystore/index.d.ts.map +1 -1
  92. package/dist/keystore/indexeddb-identity-store.d.ts +4 -0
  93. package/dist/keystore/indexeddb-identity-store.d.ts.map +1 -1
  94. package/dist/keystore/indexeddb-identity-store.js +30 -13
  95. package/dist/keystore/indexeddb-identity-store.js.map +1 -1
  96. package/dist/keystore/indexeddb-shared.d.ts +19 -2
  97. package/dist/keystore/indexeddb-shared.d.ts.map +1 -1
  98. package/dist/keystore/indexeddb-shared.js +193 -6
  99. package/dist/keystore/indexeddb-shared.js.map +1 -1
  100. package/dist/keystore/indexeddb-token-store.d.ts +15 -2
  101. package/dist/keystore/indexeddb-token-store.d.ts.map +1 -1
  102. package/dist/keystore/indexeddb-token-store.js +308 -27
  103. package/dist/keystore/indexeddb-token-store.js.map +1 -1
  104. package/dist/org-protocol.d.ts +45 -0
  105. package/dist/org-protocol.d.ts.map +1 -1
  106. package/dist/org-protocol.js +757 -11
  107. package/dist/org-protocol.js.map +1 -1
  108. package/dist/ownership-v21.d.ts +21 -4
  109. package/dist/ownership-v21.d.ts.map +1 -1
  110. package/dist/ownership-v21.js +49 -16
  111. package/dist/ownership-v21.js.map +1 -1
  112. package/dist/ownership-workflow.d.ts +30 -0
  113. package/dist/ownership-workflow.d.ts.map +1 -1
  114. package/dist/ownership-workflow.js +412 -54
  115. package/dist/ownership-workflow.js.map +1 -1
  116. package/dist/seq-tracker.d.ts +2 -0
  117. package/dist/seq-tracker.d.ts.map +1 -1
  118. package/dist/seq-tracker.js +3 -2
  119. package/dist/seq-tracker.js.map +1 -1
  120. package/dist/tools/cross-sdk-agent.d.ts +60 -3
  121. package/dist/tools/cross-sdk-agent.d.ts.map +1 -1
  122. package/dist/tools/cross-sdk-agent.js +433 -37
  123. package/dist/tools/cross-sdk-agent.js.map +1 -1
  124. package/dist/transport.d.ts +3 -0
  125. package/dist/transport.d.ts.map +1 -1
  126. package/dist/transport.js +62 -30
  127. package/dist/transport.js.map +1 -1
  128. package/dist/version.d.ts +1 -1
  129. package/dist/version.js +1 -1
  130. package/package.json +1 -1
@@ -1,10 +1,12 @@
1
1
  # Ownership 2.1 SDK 应用集成指南
2
2
 
3
- 本文面向应用开发者,以当前工作区的 Node.js TypeScript SDK 为例,说明身份准备、发起关系操作、接入审批界面或自动策略、跟踪结果与断线恢复。协议依据为 [Ownership 协议定义 2.1](../protocol/Ownership协议定义2.1.md);编排契约见 [Ownership SDK 编排指南 2.1](Ownership-SDK编排指南2.1.md),实现边界见 [Ownership 2.1 详细设计](Ownership2.1详细设计.md)。
3
+ 本文面向 EC CLI/Evolcore 等应用的集成开发者,以当前工作区的 Node.js TypeScript SDK 为例,说明身份准备、发起关系操作、接入审批界面、跟踪结果与断线恢复。主示例为 EC CLI 创建 agent 类型的 sub AID,由 Evolcore 一侧发起绑定,human owner 在自己的 App 中点击同意。EC CLI 当前尚未接入 Ownership 2.1,以下 SDK 代码是开发者需要接入的目标流程,不表示现有 CLI 已支持绑定命令。协议依据为 [Ownership 协议定义 2.1](../protocol/Ownership协议定义2.1.md);编排契约见 [Ownership SDK 编排指南 2.1](Ownership-SDK编排指南2.1.md),实现边界见 [Ownership 2.1 详细设计](Ownership2.1详细设计.md)。
4
+
5
+ 普通 `agent.md` 的基础读取、验签、上传与显式 pending 恢复不以前置 Ownership 共识、owner Storage 或关系状态为条件。普通正文更新须原样保留当前原件中全部关系材料的字段存在性、类型和值,并遵守本人签名和原 ETag/CAS;材料无效或依赖不可用不能阻断这种更新。增删改关系字段继续执行当前双文件授权核验,不能借普通名片入口清除或替换 owner 锁。
4
6
 
5
7
  需要实现或移植 SDK 内部机制时,查阅 [Ownership 2.1 SDK 开发与移植指南](Ownership2.1-SDK开发与移植指南.md);本文聚焦应用公有接口。
6
8
 
7
- 本文使用当前 [包入口](../../ts/src/index.ts) 和 [AUNClient](../../ts/src/client.ts) 的公有 API。工作区包名为 `@agentunion/fastaun`、参考版本为 `0.5.19`,要求 Node.js `>=22.16.0`,见 [package.json](../../ts/package.json)。这些信息描述当前源码,不表示同版本 npm 包已经发布或包含本工作区的全部 2.1 实现。旧 `Ownership-SDK集成指南.md`、`Ownership-SDK实现指南.md` 属于 legacy;协议 3.0 不属于本文范围。
9
+ 本文使用当前 [包入口](../../ts/src/index.ts) 和 [AUNClient](../../ts/src/client.ts) 的公有 API。工作区包名为 `@agentunion/fastaun`、参考版本为 `0.5.21`,要求 Node.js `>=22.16.0`,见 [package.json](../../ts/package.json)。这些信息描述当前源码,不表示同版本 npm 包已经发布或包含本工作区的全部 2.1 实现;EC 集成时应核对实际依赖具有本文接口与行为,不能直接假定现有旧依赖已经支持。旧 `Ownership-SDK集成指南.md`、`Ownership-SDK实现指南.md` 属于 legacy;协议 3.0 不属于本文范围。
8
10
 
9
11
  兼容方向为新服务端兼容新旧 SDK 的既有身份认证、普通名片和通信入口,并保留旧 SDK 的 legacy owner 操作;新 SDK 的 2.1 关系操作不兼容旧服务端。Ownership 2.1 当前关系始终重新核对两份当前文件;旧 SDK 的旧格式关系由隔离的 Auth JSONL、operation ID 和 NS ownership_proof 兼容,不生成 2.1 双文件或共识,也不得覆盖已存现代声明。不把新 SDK 源码调用形态兼容作为本契约要求。
10
12
 
@@ -50,56 +52,115 @@ Ownership 2.1 关系事实只来自 sub 的权威 `agent.md` 与 owner 签署、
50
52
 
51
53
  `persistence_unavailable` 表示本地任务存储能力缺失、数据库恢复不可用、任务记录损坏或原子保存失败;远端 NS ETag、owner 原件或原 NS CAS 条件变化属于 `conflict`,不是本地持久化故障。它不是连接成功后就能忽略的提示;Facade 可抛出该错误,恢复也会停止。只读共识检查不依赖本地任务存储,不能用其成功证明任务可持久化。
52
54
 
53
- ## 3. 最小 TypeScript 接入
55
+ ## 3. EC CLI 集成示例:sub 发起,human owner 同意
56
+
57
+ 本节按执行顺序展示两端接线;sub 代码运行于 EC/Evolcore 的 AUN 运行层,owner 代码运行于 owner 自己的 Node.js App 后端。owner 的人机界面调用该后端审批;浏览器 SDK 的身份存储按其自身平台接口接入,不直接使用 Node.js 文件存储。
58
+
59
+ ### 3.1 EC CLI 创建 sub 身份
60
+
61
+ EC 现有创建入口如下,`<EC持久目录>` 替换为本机固定绝对目录;本例创建普通 agent,不在注册时指定 owner:
62
+
63
+ ```bash
64
+ ec aid new helper.agentid.pub --aun-path "<EC持久目录>" --format json
65
+ ```
66
+
67
+ 命令注册身份并尝试上传普通 agent 名片,应用按业务需要检查 agentmdUploaded,失败时可用现有 `ec aid agentmd put helper.agentid.pub --aun-path "<EC持久目录>"` 显式重试。普通名片发布成功不是关系绑定前提;EC 开发者仍需接入第 3.4 节运行层。现有扫码绑定和本地 owners[] 不等于 Ownership 共识。
54
68
 
55
- ### 3.1 装载存量身份
69
+ ### 3.2 两端分别装载自己的身份
56
70
 
57
- 以下 `appConfig` 由应用自行读取,类型为 `{ aunPath: string; encryptionSeed: string; rootCaPath: string }`。`aunPath` 为固定持久绝对目录,`encryptionSeed` 从应用自己的秘密配置提供;这些不是 `AUNClient` 构造参数。
71
+ 以下公用装载函数分别放在两端代码中。`subConfig` 必须沿用 EC 创建身份时的同一 `aunPath` 与身份解密配置,并使用运行层固定的 slot,不能换用 SDK 默认 `.aun` 或另一 seed;当前 EC 的 seed 策略固定为 `evol`。`ownerConfig` 来自 owner App 自己的独立存储,`owner.agentid.pub` 已注册为 human。两者都应配置可信根。配置字段不是 `AUNClient` 构造参数。
58
72
 
59
73
  ```ts
60
74
  import { AIDStore, AUNClient } from '@agentunion/fastaun';
61
- const store = new AIDStore({
62
- aunPath: appConfig.aunPath, encryptionSeed: appConfig.encryptionSeed,
63
- rootCaPath: appConfig.rootCaPath, verifySsl: true, slotId: 'ownership-app',
64
- });
65
- const loaded = store.load('helper.agentid.pub');
66
- if (!loaded.ok) throw new Error(loaded.error.message);
67
- if (!loaded.data.aid.isPrivateKeyValid()) throw new Error('本身份私钥不可用');
68
- const client = new AUNClient(loaded.data.aid);
75
+ type IdentityConfig = { aunPath: string; encryptionSeed: string; rootCaPath: string; slotId: string };
76
+ function loadOwnClient(aid: string, config: IdentityConfig): AUNClient {
77
+ const store = new AIDStore({ ...config, verifySsl: true });
78
+ const loaded = store.load(aid);
79
+ if (!loaded.ok) throw new Error(loaded.error.message);
80
+ if (!loaded.data.aid.isPrivateKeyValid()) throw new Error('本身份私钥不可用');
81
+ return new AUNClient(loaded.data.aid);
82
+ }
69
83
  ```
70
84
 
71
- 构造函数接收 `AID` 对象或无参,不接收 AID 字符串、配置对象或其它身份的凭据。需要延后装载时,可在无身份或已关闭状态调用 `loadIdentity(aid)`;无参构造会先使用默认数据配置,本例直接传入已装载的 AID,使客户端沿用其 `aunPath`、设备、slot、TLS 和可信根配置。连接选项传给 `connect()`,不是构造函数。
85
+ 构造函数接收 `AID` 对象或无参,不接收 AID 字符串、配置对象或其它身份的凭据。需要延后装载时,可在无身份或已关闭状态调用 `loadIdentity(aid)`。本例直接传入已装载的 AID,使客户端沿用其持久目录、设备、slot、TLS 和可信根配置。连接选项传给 `connect()`。
86
+
87
+ 两端共用以下事件订阅方式。`updateOwnershipView(event: string, payload: Parameters<EventHandler>[0]): void | Promise<void>` 由应用实现,保存任务进度并更新 CLI 状态或 App 界面;事件直接携带载荷,没有 `event.data` 包装。
88
+
89
+ ```ts
90
+ import type { EventHandler } from '@agentunion/fastaun';
91
+ const events = ['ownership.action_required', 'ownership.progress', 'ownership.completed',
92
+ 'ownership.rejected', 'ownership.stopped', 'ownership.error'];
93
+ function watchOwnership(client: AUNClient): void {
94
+ for (const event of events) client.on(event, payload => updateOwnershipView(event, payload));
95
+ }
96
+ ```
72
97
 
73
- ### 3.2 首次注册的独立分支
98
+ ### 3.3 owner App 先订阅审批,再连接
74
99
 
75
- 没有本地身份时,先通过同一个 `AIDStore` 注册,再执行上述装载流程。下面是首次注册分支,不是每次启动都执行的步骤:
100
+ owner App 展示 SDK 已验证的 `ownership.request`,包含操作、sub、owner、版本和发起方。`EventHandler` 是通用载荷,下面先收窄 `operation_id`;其余展示字段按第 5 节解析。`showOwnerApproval(payload: Parameters<EventHandler>[0], decide: (accept: boolean) => Promise<void>): void` 由 App 实现:展示同意/拒绝按钮,用户点击时才调用 `decide`,并处理其异步错误;同一 ID 幂等更新界面。它不是 SDK 内置 UI。
76
101
 
77
102
  ```ts
78
- const registered = await store.register('helper.agentid.pub', {
79
- type: 'agent', owner: 'owner.agentid.pub',
103
+ const ownerClient = loadOwnClient('owner.agentid.pub', ownerConfig);
104
+ ownerClient.on('ownership.request', payload => {
105
+ if (!payload || typeof payload !== 'object' || Array.isArray(payload)) return;
106
+ const operationId = 'operation_id' in payload ? payload.operation_id : undefined;
107
+ if (typeof operationId !== 'string') return;
108
+ showOwnerApproval(payload, accept => decideOwner(operationId, accept));
80
109
  });
81
- if (!registered.ok) throw new Error(registered.error.message);
110
+ watchOwnership(ownerClient);
111
+ await ownerClient.connect({ auto_reconnect: true });
82
112
  ```
83
113
 
84
- `register()` 返回 `Result<{ registered: true }>`,并尝试以本身份条件创建初始名片。`type: 'agent'` 的 `owner` 可省略;省略时只初始化普通 `agent.md`,不保存 Ownership 关系意图。有 owner 时保存固定 `operation_id` 的 owner 注册意图;初始名片不直接写入 owner 关系,首次连接后 SDK 用原意图继续绑定,owner 仍须审批。应用需确认初始名片已可用,不能把 `registered: true` 当作关系建立完成,也不能再调用绑定发起接口来“继续注册”。`type: 'human'` 禁止提供 owner,`group/org` 要求当前 owner 并沿用专属生命周期。注册与恢复见 [AIDStore.register](../../ts/src/aid-store.ts) 和 [设计第 7.1 节](Ownership2.1详细设计.md#71-七个-facade-与内部复用)。
114
+ 按钮回调处理原任务。`saveBusinessTask(task: OwnershipTaskResult): Promise<void>` 是应用自实现的业务持久化函数,保存任务 ID、参与方、版本、状态与阶段;异常按第 9 节处理。
115
+
116
+ ```ts
117
+ async function decideOwner(operationId: string, accept: boolean): Promise<void> {
118
+ const result = accept
119
+ ? await ownerClient.acceptOwnershipRequest(operationId)
120
+ : await ownerClient.rejectOwnershipRequest(operationId, '用户拒绝');
121
+ await saveBusinessTask(result);
122
+ }
123
+ ```
124
+
125
+ 请求回调只展示界面,不在收到事件时自动同意,也不等待用户操作而阻塞事件处理。owner 不再调用 `bindSubaid` 创建反向申请。human 可作为 owner;被禁止的是 human 自己作为 sub 声明 owner。
85
126
 
86
- ### 3.3 先订阅,再连接
127
+ ### 3.4 EC/Evolcore 的 sub 发起绑定
87
128
 
88
- 事件处理器类型是 `(payload) => void | Promise<void>`,直接收到载荷,没有 `event.data` 包装。以下 `showApproval`、`updateOwnershipView` 为应用自实现函数;签名分别为 `showApproval(payload: Parameters<EventHandler>[0]): void`、`updateOwnershipView(event: string, payload: Parameters<EventHandler>[0]): void | Promise<void>`。应用负责按第 5 节字段解析、保存和展示载荷。
129
+ 以下展示 sub 运行层尚无客户端时的初始化;已有客户端时直接复用,不再次装载和连接。先订阅结果事件,再连接,最后由 CLI 用户指令触发一次申请。sub 发起即表达自己的同意,不需要 sub UI,也不再调用审批方法。
89
130
 
90
131
  ```ts
91
- import type { EventHandler } from '@agentunion/fastaun';
92
- const onRequest: EventHandler = payload => showApproval(payload);
93
- client.on('ownership.request', onRequest);
94
- const events = ['ownership.action_required', 'ownership.progress', 'ownership.completed',
95
- 'ownership.rejected', 'ownership.stopped', 'ownership.error'];
96
- for (const event of events) client.on(event, payload => updateOwnershipView(event, payload));
97
- await client.connect({ auto_reconnect: true });
132
+ const subClient = loadOwnClient('helper.agentid.pub', subConfig);
133
+ watchOwnership(subClient);
134
+ await subClient.connect({ auto_reconnect: true });
135
+ const task = await subClient.bindOwneraid('owner.agentid.pub');
136
+ await saveBusinessTask(task);
137
+ ```
138
+
139
+ `pending` 是正常等待审批或远端材料的结果;Promise 返回、消息 ACK、owner 点击同意均不等于完成。EC 应让持久运行层继续保持 sub SDK 在线,处理 owner 的批准和后续文件交换;CLI 可返回原 `operation_id`,不能因发起接口返回就终止唯一的 sub 运行实例。重连由 SDK 恢复同一任务,不重新调用绑定。若复用 EC 已有客户端,应在其连接前订阅并复用该实例,不为此流程另开同一消费身份的竞争连接。
140
+
141
+ 各端通过 `ownership.completed` 记录本端任务目标已新鲜核验。owner App 查看当前关系必须显式传 sub AID;省略参数会检查 human owner 自己:
142
+
143
+ ```ts
144
+ const current = await ownerClient.checkOwnershipConsensus('helper.agentid.pub');
145
+ showConsensus(current);
98
146
  ```
99
147
 
100
- `connect()` 使用已装载身份完成认证。连接及重连成功后会在后台触发注册意图和 Ownership 任务恢复,`await connect()` 返回不代表所有恢复任务完成。连接前订阅可接到恢复中的审批或终局事件;页面卸载时可对 `on()` 返回的 `Subscription` 调用 `unsubscribe()`。接线见 [AUNClient](../../ts/src/client.ts) 和 [事件类型](../../ts/src/events.ts)。
148
+ `showConsensus(result: OwnershipConsensusResult): void` 为 App 自实现函数;仅在 `status === 'consensus'` 且 owner 与 sub 匹配时展示当前绑定成立,六态和授权边界见第 7 节。两端均先订阅再连接;`connect()` 返回不代表后台注册意图或任务恢复已结束。页面卸载可调用 `on()` 返回的 `Subscription.unsubscribe()`。真实接线见 [AUNClient](../../ts/src/client.ts)、[事件类型](../../ts/src/events.ts) 和 [工作流实现](../../ts/src/ownership-workflow.ts)。
101
149
 
102
- ### 3.4 通用签验与多签名片
150
+ ### 3.5 首次注册时携带 owner 的替代分支
151
+
152
+ 开发者也可在首次注册时保存 owner 意图。下面替代第 3.1 节的无 owner 创建及第 3.4 节的显式申请,不与它们重复执行;`store` 是按 subConfig 创建的 AIDStore:
153
+
154
+ ```ts
155
+ const registered = await store.register('helper.agentid.pub', {
156
+ type: 'agent', owner: 'owner.agentid.pub',
157
+ });
158
+ if (!registered.ok) throw new Error(registered.error.message);
159
+ ```
160
+
161
+ `register()` 返回 `Result<{ registered: true }>`,并尝试以本身份条件创建初始名片。`type: 'agent'` 的 `owner` 可省略;省略时只初始化普通 `agent.md`,不保存 Ownership 关系意图。有 owner 时保存固定 `operation_id` 的 owner 注册意图;初始名片不直接写入 owner 关系,首次连接后 SDK 用原意图继续绑定,owner 仍须审批。应用需确认初始名片已可用,不能把 `registered: true` 当作关系建立完成,也不能再调用绑定发起接口来“继续注册”。`type: 'human'` 禁止提供 owner,`group/org` 要求当前 owner 并沿用专属生命周期。注册与恢复见 [AIDStore.register](../../ts/src/aid-store.ts) 和 [设计第 7.1 节](Ownership2.1详细设计.md#71-七个-facade-与内部复用)。
162
+
163
+ ### 3.6 通用签验与多签名片
103
164
 
104
165
  应用通过 `AIDStore.sign/verify` 使用通用签验,TS/JS 两者均须 await,返回 `Promise<Result>`。默认 `format: 'raw'` 生成/验证 detached Base64 签名;`format: 'document'` 返回签后全文与签名列表,verify 返回 valid、status、payload 和逐块 signatures。先检查外层 ok,再判断验签 valid;数学失败保留全部逐块结果,resolver 操作异常是外层 error。详细参数及四语言命名见 [API 手册](06-API手册.md#通用-sign--verify)。
105
166
 
@@ -131,7 +192,7 @@ await client.connect({ auto_reconnect: true });
131
192
 
132
193
  ```ts
133
194
  import type { OwnershipTaskResult } from '@agentunion/fastaun';
134
- const task: OwnershipTaskResult = await client.bindOwneraid('owner.agentid.pub');
195
+ const task: OwnershipTaskResult = await subClient.bindOwneraid('owner.agentid.pub');
135
196
  await saveBusinessTask(task);
136
197
  ```
137
198
 
@@ -151,7 +212,7 @@ await saveBusinessTask(task);
151
212
  | `requester_aid` | 仅 `ownership.request` 附带,经消息层确认的发起方;不能从任意聊天文本自报字段推导审批身份。 |
152
213
  | `local_roles` | 本端承担的 `owner`、`sub`、`new_owner` 角色数组;同一 AID 可同时承担多个角色。当前实现为各 Ownership 本地事件附带它。 |
153
214
  | `base_relation_version`、`target_relation_version` | 本次固定审批上下文,不允许 UI 在批准时替换目标。 |
154
- | `relation_version` | SDK 已核验目标时附带的版本;未核验时可缺省,不能用它替代新鲜共识。 |
215
+ | `relation_version` | SDK 已核验本任务时附带的实际验收版本:release 按 released/v 返回 v、按 unbound/0 返回 0;base/target 仍固定 v。已有历史事件依据原验收记录,未核验时可缺省,不能替代当前新鲜共识。 |
155
216
  | `status`、`step`、`code?`、`reason?`、`retryable?` | 当前任务及错误展示;错误字段按实际存在处理。 |
156
217
 
157
218
  | 事件 | 应用处理 |
@@ -159,19 +220,19 @@ await saveBusinessTask(task);
159
220
  | `ownership.request` | 显示同意/拒绝或交给明确的自动策略;策略未决定时保持待审批。 |
160
221
  | `ownership.action_required` | 提示释放后 sub 的名片清理缺少应用明确授权;处理见第 6.2 节。 |
161
222
  | `ownership.progress` | 更新本端进度,不宣布关系成立。 |
162
- | `ownership.completed` | 记录本任务目标已核验;清理、副本同步和凭据交接另行跟踪。 |
223
+ | `ownership.completed` | 记录本任务目标已核验;关系清理和凭据交接另行跟踪;普通名片副本独立同步。 |
163
224
  | `ownership.rejected` | 本次审批拒绝,不回滚已验收的历史关系。 |
164
225
  | `ownership.stopped` | 本次流程不再推进;不是关系解锁通知。 |
165
226
  | `ownership.error` | 展示错误和可重试提示,核对载荷中的任务状态;已完成关系的后续清理错误单独展示。 |
166
227
 
167
- `EventHandler` 是通用载荷类型,不能把回调参数直接当作一个已声明的专用请求类型。应用的 `showApproval` 应解析本端请求字段并保存 `operation_id`,再产生自己的界面决定。下面的 `appApproval` 由该 UI 或自动策略提供,类型为 `{ operation_id: string; accept: boolean; reason?: string }`;`showOwnershipError(code: string, retryable: boolean): void` 也是应用自实现函数。
228
+ `EventHandler` 是通用载荷类型,不能把回调参数直接当作一个已声明的专用请求类型。第 3.3 节的 `showOwnerApproval` 应解析本端请求字段并保存 `operation_id`,再产生自己的界面决定。下面展示其按钮回调中的错误处理;`appApproval` 由该 UI 提供,类型为 `{ operation_id: string; accept: boolean; reason?: string }`;`showOwnershipError(code: string, retryable: boolean): void` 也是应用自实现函数。
168
229
 
169
230
  ```ts
170
231
  import { AUNError } from '@agentunion/fastaun';
171
232
  try {
172
233
  const result = appApproval.accept
173
- ? await client.acceptOwnershipRequest(appApproval.operation_id)
174
- : await client.rejectOwnershipRequest(appApproval.operation_id, appApproval.reason);
234
+ ? await ownerClient.acceptOwnershipRequest(appApproval.operation_id)
235
+ : await ownerClient.rejectOwnershipRequest(appApproval.operation_id, appApproval.reason);
175
236
  await saveBusinessTask(result);
176
237
  } catch (error) {
177
238
  if (error instanceof AUNError) showOwnershipError(error.stringCode, error.retryable);
@@ -204,7 +265,7 @@ sub 收到 release 通知时,可使用本人明确 accept、含 sub 角色,
204
265
 
205
266
  释放清理不能调用 `acceptOwnershipRequest`/`rejectOwnershipRequest`,这两个接口会拒绝 release 任务。应用明确决定清理后,由 sub 用自己的身份通过现有 `AIDStore.uploadAgentMd(subAid, content)` 自签上传清除旧 `owner`、`ownership` 的名片,遵守当前 NS 条件与代际,不能指定其它上传身份或覆盖后续关系。新鲜有效名片的关系字段已清空时,SDK 仅在本任务持久清理原件、摘要、原 CAS,或本人明确 accept 的匹配原 bind/transfer.release_cleanup,与当前 NS 原文、摘要、ETag及已知提交 ETag 精确对应后观察完成;空字段本身不证明该任务完成,也不补造 sub 的清理同意或历史条件。
206
267
 
207
- 已完成的历史绑定/转移或释放任务保持历史完成,但当前关系必须从两份权威材料重新判断:旧声明仍在且释放依据有效时为 `released`,名片清理后为 `unbound`、版本 `0`。NS 不保留释放终局或历史版本上界,材料不可确认时不得沿用历史释放结果作当前授权。详细释放与清理规则见 [编排指南第 2.4 节](Ownership-SDK编排指南2.1.md#24-应用层-facade编排审批与共识检查) 和 [协议第 4.2 节](../protocol/Ownership协议定义2.1.md#42-解绑)。
268
+ 已完成的历史绑定/转移或释放任务保持历史完成,但当前关系必须从两份权威材料重新判断:旧声明仍在且释放依据有效时为 `released`,关系字段清理后为 `unbound`、版本 `0`。NS 不保留释放终局或历史版本上界,材料不可确认时不得沿用历史释放结果作当前授权。详细释放与清理规则见 [编排指南第 2.4 节](Ownership-SDK编排指南2.1.md#24-应用层-facade编排审批与共识检查) 和 [协议第 4.2 节](../protocol/Ownership协议定义2.1.md#42-解绑)。
208
269
 
209
270
  ### 6.3 三方转移
210
271
 
@@ -217,18 +278,18 @@ sub 收到 release 通知时,可使用本人明确 accept、含 sub 角色,
217
278
  | 情形 | 本端决定与文件要求 |
218
279
  | --- | --- |
219
280
  | 建立 self-owner | sub 调用 `bindOwneraid(自己的 AID)`,或 owner 角色调用 `bindSubaid(自己的 AID)`;一次发起覆盖本端两个角色,仍分别签署、提交双文件。 |
220
- | 外部 owner → self-owner | 原外部 owner 发起转移,目标为 sub;sub 同时承担 `sub` 和 `new_owner`,一个审批决定覆盖两角色,先发布自己的 owner 文件再提交名片。 |
281
+ | 外部 owner → self-owner | 原外部 owner 发起转移,目标为 sub;sub 同时承担 `sub` 和 `new_owner`,一个审批决定覆盖两角色,先发布自己的 owner 文件再提交关系文件。 |
221
282
  | self-owner → 外部 owner | 同一 AID 兼任原 owner 与 sub,发起意愿覆盖这两个本端角色,外部新 owner 仍须审批。 |
222
283
 
223
284
  SDK 合并同一接收 AID 的请求,不给自己发送 P2P。self-owner 仍要验证双文件并建立锁;`human` 不能声明 owner,包括自拥有;SDK 在任务、消息和文件副作用前拒绝此绑定。原 owner 与新 owner 相同不是有效转移。业务若要求外部管理方,还须检查 `owner_aid != sub_aid`,不能仅凭 self-owner 的 `consensus` 满足该要求。参见 [协议第 4.5 节](../protocol/Ownership协议定义2.1.md#45-self-owner-的建立解绑与转移)。
224
285
 
225
286
  ## 7. 任务完成与当前共识六态
226
287
 
227
- 任务状态回答“这一个本端业务任务推进到哪里”,共识状态回答“当前两份权威材料证明什么关系”。普通主体适用下表六态;Group/Org 作为 `sub` 调用共识检查时返回特殊 `status/code=not_applicable`、`retryable=false`,不属于六态。P2P 投递成功、ACK、对端 `relation.confirmed` 提示或本地阶段标记都不是任务完成证据。绑定/转移的完成要求新鲜 NS 目标 owner、目标版本与本任务文件材料匹配;原 owner 必须有本任务已保存的转移授权,接收方固定首次验证授权的全文摘要及实际期限,不接受恢复时换字节或延期;释放完成要求新鲜 `released/v`,或按本任务原件严格关联的真实 `unbound/0`,任务起始、目标及历史 verified 版本仍为 `v`;历史完成记录不替代之后的当前关系查询。
288
+ 任务状态回答“这一个本端业务任务推进到哪里”,共识状态回答“当前两份权威材料证明什么关系”。普通主体适用下表六态;Group/Org 作为 `sub` 调用共识检查时返回特殊 `status/code=not_applicable`、`retryable=false`,不属于六态。P2P 投递成功、ACK、对端 `relation.confirmed` 提示或本地阶段标记都不是任务完成证据。绑定/转移的完成要求新鲜 NS 目标 owner、目标版本与本任务文件材料匹配;原 owner 必须有本任务已保存的转移授权,接收方固定首次验证授权的全文摘要及实际期限,不接受恢复时换字节或延期;释放完成要求新鲜 `released/v`,或按本任务原件严格关联的真实 `unbound/0`,任务起始、目标版本保持 `v`,共识验收证据及公共事件 relation_version 使用该任务实际验收的 released/v 或 unbound/0;已有历史验收记录不改写,也不替代之后的当前关系查询。
228
289
 
229
290
  ```ts
230
291
  import type { OwnershipConsensusResult } from '@agentunion/fastaun';
231
- const consensus: OwnershipConsensusResult = await client.checkOwnershipConsensus('helper.agentid.pub');
292
+ const consensus: OwnershipConsensusResult = await ownerClient.checkOwnershipConsensus('helper.agentid.pub');
232
293
  showConsensus(consensus);
233
294
  ```
234
295
 
@@ -247,12 +308,14 @@ showConsensus(consensus);
247
308
 
248
309
  四 SDK 普通名片下载的 `verification.ownership_status` 仍是 legacy proof 展示字段,不是 2.1 授权结果。文件签名有效或旧展示状态为 complete 不能证明 2.1 共识;该展示字段对 2.1 名片显示不完整或其他旧状态也不能代替当前关系检查。应用使用 `checkOwnershipConsensus(subAid)` 获取 2.1 新鲜结果。
249
310
 
250
- 关系完成、sub 字段清理、旧 owner 文件条件清理、NS 向 Storage 同步名片副本、应用凭据交接应分别展示。Storage 副本尚未同步不否定 NS 已完成的验收;反过来,本地或 Storage 上的旧名片也不能覆盖当前两份权威材料的共识。
311
+ 关系完成、subject 关系字段清理、旧 owner 文件清理和凭据交接分别展示。普通名片副本独立同步,不参与关系验收,也不替代两个当前关系文件。
251
312
 
252
313
  敏感业务在执行时由执行端核对当前 owner、sub、关系版本、权限范围和新鲜共识,并保存授权证据;UI 布尔值、历史完成事件和旧 token 不替代该校验。若业务使用 token/ACL,应把它们绑定到完整关系声明及其版本,并新鲜检查释放、转移后的有效性;清理后重新绑定可能再次使用版本 `1`,版本号不能单独识别关系。完整授权边界见 [协议第 6 节](../protocol/Ownership协议定义2.1.md#6-共识审计与安全边界)。
253
314
 
254
315
  ## 8. 断线与重启恢复
255
316
 
317
+ 0.5.20、0.5.19 及更早任务按原格式及原有协议边界兼容;保留原 operation、有效审批、原签名字节和原提交条件,不能因缺少后增本地字段而一律停止或新建任务。历史适配、绑定容错和无参数 reset 的完整范围见 [编排指南第 8 节](Ownership-SDK编排指南2.1.md#8-崩溃与响应丢失后的恢复)。reset 只归档当前身份发起的未完成任务,保留原记录和远端文件,迟到消息不能复活。 旧 Owner 候选尚未发布时,原 `expected_revision` 必须有权威证据精确匹配,不能用当前 version 替代;服务未提供旧 revision 证据时保留原件及任务并返回 unavailable。目标已提交但任务仍待恢复时,只有本地原始签名候选与当前双方共识精确匹配才确认完成;缺少这些证据不能从当前网络补造历史原件或提交条件。
318
+
256
319
  1. 启动时恢复原 `aunPath`、密钥解密配置、稳定设备和 slot,装载同一身份,先注册事件处理器再连接。
257
320
  2. SDK 从自己的持久任务继续审批、已签文件和待发送通知;请求重发和响应丢失的恢复复用原字节与原提交条件。恢复先核对权威关系和本任务证据,旧任务不能覆盖后续代际。
258
321
  3. 应用从自己的数据库恢复业务记录与 `operation_id`,幂等更新 UI。待审批请求可再次通知;已经保存的决定不重新作相反选择。
@@ -262,7 +325,7 @@ showConsensus(consensus);
262
325
 
263
326
  重复发起相同进行中操作会复用原 `operation_id`、审批、签名字节、提交条件和授权期限;匹配要求本端身份、发起方、操作、全部参与方及起始/目标关系版本一致。同代际不同进行中意图返回 conflict,不产生第二任务。拒绝、停止、不可重试 error 不复活;后续代际的新合法操作使用新任务,历史 completed 不仅凭参数相同复用。不要删除任务数据库、清除审批记录、删除 `owner.md` 或刷新条件来制造“恢复成功”;删除 owner 的权威文件本身可能导致释放,含义不是取消任务。
264
327
 
265
- Group/Org 名片失败稿及 pending 保留实体命名空间中的完整多签原文、原 CAS、固定 owner 和实体证书指纹,由应用显式重试,post-connect/重连不隐式 PUT。重试先验证完整原件及当前 owner、状态和证书代际,原条件完整且同代际原文/ETag 已确认提交时只观察完成。转移、rekey 或解散后停止旧代际待办,不更换身份、指纹或条件重签。取消实体 V2 授权后,不再保存、刷新或检查其额外授权及过期窗口;普通文件签名与当前证书检查保留。专属 create/transfer 自身 checkpoint 恢复机制不变。
328
+ Group/Org 名片失败稿及 pending 保留实体命名空间中的完整多签原文、原 CAS、固定 owner 和实体证书指纹,由应用显式重试,post-connect/重连不隐式 PUT。重试先验证完整原件及当前 owner、状态和证书代际,原条件完整且同代际原文/ETag 已确认提交时只观察完成。转移、rekey 或解散后停止旧代际待办,不更换身份、指纹或条件重签。新 SDK 现代上传不再保存、刷新或检查额外 V2 授权及过期窗口;旧 V2 兼容入口仍按协议 §2.5 校验;普通文件签名与当前证书检查保留。专属 create/transfer 自身 checkpoint 恢复机制不变。
266
329
 
267
330
  ## 9. 错误处理与安全降级
268
331
 
@@ -1,12 +1,14 @@
1
1
  # Ownership 2.1 SDK 开发与移植指南
2
2
 
3
- 本文面向实现或移植其它语言 SDK 的作者,以当前工作区的 Node TypeScript SDK 为实现参考,说明内部职责、文件验证、条件提交、P2P 编排、持久化与验收。应用如何发起操作及处理审批,见 [SDK 应用集成指南](Ownership2.1-SDK应用集成指南.md);编排契约见 [SDK 编排指南 2.1](Ownership-SDK编排指南2.1.md),完整文件格式和服务端授权要求以 [Ownership 协议定义 2.1](../protocol/Ownership协议定义2.1.md) 为准。
3
+ 本文面向实现 Rust 等新语言 SDK 或移植其它语言 SDK 的开发者,以当前工作区的 Node TypeScript SDK 为实现参考,说明内部职责、文件验证、条件提交、P2P 编排、持久化与验收。EC CLI 等应用接入方如何发起操作及处理审批,见 [SDK 应用集成指南](Ownership2.1-SDK应用集成指南.md);编排契约见 [SDK 编排指南 2.1](Ownership-SDK编排指南2.1.md),完整文件格式和服务端授权要求以 [Ownership 协议定义 2.1](../protocol/Ownership协议定义2.1.md) 为准。
4
+
5
+ 普通 `agent.md` 的基础读取、验签、上传与显式 pending 恢复不以前置 Ownership 共识、owner Storage 或关系状态为条件。普通正文更新须原样保留当前原件中全部关系材料的字段存在性、类型和值,并遵守本人签名和原 ETag/CAS;材料无效或依赖不可用不能阻断这种更新。增删改关系字段继续执行当前双文件授权核验,不能借普通名片入口清除或替换 owner 锁。
4
6
 
5
7
  设计依据还包括 [Ownership 2.1 详细设计](Ownership2.1详细设计.md) 与 [TDD 分阶段实施计划](Ownership2.1-TDD分阶段实施计划.md)。下文分别说明协议要求和 TypeScript 的实际接线;设计要求不能直接作为某个运行环境已经验收的证据。TypeScript 是接线与组织方式的参考,不是全部差异的默认裁决版本;各项以协议和冻结契约为准,逐项采用哪个 SDK 的正确行为见 [审查报告第十二节](../audit/Ownership2.1代码审查报告.md#十二2026-10-11-本轮复审与修复)和[审查报告第十三节](../audit/Ownership2.1代码审查报告.md#十三2026-10-13-审查更正与最小修复验收)。旧集成、实现指南中的 proof、自动 escrow 和 bindAid/bindOwner 流程属于 legacy;协议 3.0 不在本文范围。
6
8
 
7
- 参考包在 [ts/package.json](../../ts/package.json) 中标为 `@agentunion/fastaun`、`0.5.19`,运行要求为 Node `>=22.16.0`。这些是工作区标识,不表示本文描述的 2.1 实现已发布到该版本的软件包。
9
+ 参考包在 [ts/package.json](../../ts/package.json) 中标为 `@agentunion/fastaun`、`0.5.21`,运行要求为 Node `>=22.16.0`。这些是工作区标识,不表示本文描述的 2.1 实现已发布到该版本的软件包。
8
10
 
9
- 兼容方向为新服务端保留旧 SDK 的既有身份认证、普通名片、通信及 legacy owner 操作;新 SDK 的 2.1 关系操作不兼容旧服务端,不要求新 SDK 源码调用形态兼容。旧注册、绑定、转移、查询和解绑 RPC 以隔离的 Auth JSONL 和 NS `ownership_proof` 承载兼容状态,不生成 2.1 双文件,不构成 2.1 授权、owner 锁、版本或共识;不得覆盖已存现代声明,见 [协议开篇与 §3.2](../protocol/Ownership协议定义2.1.md#32-判定顺序)。
11
+ 兼容方向为新服务端保留旧 SDK 的既有身份认证、普通名片、通信及 legacy owner 操作;新 SDK 的 2.1 关系操作不兼容旧服务端,不要求新 SDK 源码调用形态兼容。旧注册、绑定、转移、查询和解绑 RPC 以隔离的 Auth JSONL 和 NS `ownership_proof` 承载兼容状态,不生成 2.1 双文件,不构成 2.1 授权、owner 锁、版本或共识;不得覆盖已存现代声明,见 [协议开篇与 §3.2](../protocol/Ownership协议定义2.1.md#32-判定顺序与普通名片边界)。
10
12
 
11
13
  ## 1. 实现边界与角色
12
14
 
@@ -23,7 +25,7 @@
23
25
 
24
26
  Ownership 是 `agent.md` 上叠加的可选关系属性。基础名片解析、普通读取和外层签名验证应与关系验证分层;仅 Ownership 字段或关系材料无效,不得据此判定基础 `agent.md` 无效。关系为 `invalid` 或 `unavailable` 时,只停止或降级依赖当前 owner 关系的授权、共识和关系操作;普通 `agent.md` 下载、基础验签及通信继续。普通读取兼容没有 Ownership 专用 Header 的旧 SDK;新 SDK 的关系操作仍执行当前协议验证。
25
27
 
26
- Group/Org 名片由实体私钥生成主签,当前 owner 以本人 token 上传,无需实体登录;可选一个或多个 owner 附签,每个都须为当前 owner,存在就必须验全部块。Group 旧实体单签及实体身份上传始终兼容,Org 不开放该旧入口。取消实体额外 V2 上传授权,保留当前 owner、生命周期、实体证书代际与 CAS 检查,见 [协议 §2.5](../protocol/Ownership协议定义2.1.md#25-grouporg-名片的实体主签与-owner-上传)。 实体 fresh GET 必须同时携带 `X-AUN-Ownership-Check: 1`、`Cache-Control: no-cache`、`X-AUN-Signature-Format: multi-v1`;NS 仅凭 Check 头绕过 LRU 并新鲜验证全部签块,仍返回 not_applicable,不进入通用 Ownership 账本。 fresh GET/HEAD 保留 current/stale、权威 owner/实体指纹头与对应表示 ETag;真正缺失为 404,权威依赖失败为 503。verified 下载逐块验证历史证书及原字节,历史成功不代表当前权限。
28
+ Group/Org 名片由实体私钥生成主签,当前 owner 以本人 token 上传,无需实体登录;实体单签及带 owner 附签的双签/多签均可,每个附签都须为当前 owner,存在就必须验全部块。Group 旧实体单签及实体身份上传始终兼容,Org 不开放该实体身份旧入口。新 SDK 现代上传取消额外 V2 授权,保留当前 owner、生命周期、实体证书代际与 CAS 检查;服务端另保留旧0.5.19单块 owner 主签 V2 入口及原 HTTP 条件,见 [协议 §2.5](../protocol/Ownership协议定义2.1.md#25-grouporg-名片的实体主签与-owner-上传)。 实体 fresh GET 必须同时携带 `X-AUN-Ownership-Check: 1`、`Cache-Control: no-cache`、`X-AUN-Signature-Format: multi-v1`;NS 仅凭 Check 头绕过 LRU 并新鲜验证全部签块,仍返回 not_applicable,不进入通用 Ownership 账本。 fresh GET/HEAD 保留 current/stale、权威 owner/实体指纹头与对应表示 ETag;真正缺失为 404,权威依赖失败为 503。verified 下载逐块验证历史证书及原字节;单块显式 owner 主签旧实体使用该 owner 历史证书,不将正文实体指纹绑定到 owner 证书。历史成功不代表当前权限,例外不用于现代写入或多块 owner 主签。独立 AIDStore 上传实体名片时,Python/Go 须注入权威 entity owner resolver,返回 owner_aid 与 entity_cert_fingerprint;TS/JS 默认通过 fresh NS 与 PKI 核对当前 owner、实体类型及证书指纹,不能把 Client 的接线视为四端 AIDStore 都有的默认能力。
27
29
 
28
30
  关系通过现有 `GET/HEAD/PUT /agent.md` 和通用 Storage 操作建立;不新增 ownership 专用 RPC。SDK 的请求、同意、拒绝和 ready 消息是普通加密 P2P 载荷,不是服务端关系授权接口。托管是应用显式选择的能力,绑定、释放和转移均不以托管为前提。
29
31
 
@@ -236,9 +238,9 @@ TypeScript 前六个方法返回 `Promise<OwnershipTaskResult>`,`checkOwnershi
236
238
  | `ownership.stopped` | 本次推进已停止或被后续版本替代。 |
237
239
  | `ownership.error` | 无法推进或核验;completed 后的通知/清理失败也可触发,保留已提交关系及待办。 |
238
240
 
239
- 事件直接传 payload,不要求应用读取 `event.params`。载荷包含公共任务字段和 `local_roles`;request 另含可信 `requester_aid`,已核验时附 `relation_version`。这些是 SDK 本地 dispatcher 事件,不是服务端事件类型,也不通过 P2P 转发。TypeScript 的 `emit` 在持久保存后排入 microtask;恢复可能再次通知,应用按 operation_id、事件名、step 幂等处理。
241
+ 事件直接传 payload,不要求应用读取 `event.params`。载荷包含公共任务字段和 `local_roles`;request 另含可信 `requester_aid`,已核验时附该任务实际验收的 `relation_version`,release 的 released/v 对应 v、unbound/0 对应 0,不能直接用内部目标版本标记代替,已有历史验收记录不改写。这些是 SDK 本地 dispatcher 事件,不是服务端事件类型,也不通过 P2P 转发。TypeScript 的 `emit` 在持久保存后排入 microtask;恢复可能再次通知,应用按 operation_id、事件名、step 幂等处理。
240
242
 
241
- 绑定/转移 completed 需要当前双方有效共识、指定 owner 和目标版本;TypeScript `confirm` 还核对本端明确同意,并按本端角色比较自己保存的 agent/owner 全文摘要。释放 completed 接受本任务声明 `v` 的新鲜 `released/v`,或由本任务原件严格关联的真实 `unbound/0` 完成证据;任务起始、目标及历史 verified 版本仍为 `v`。sub 离线或字段未清理不妨碍原 owner 以新鲜 released 完成,历史完成不替代当前关系检查。通知已发送、消息 ACK、ready、relation.confirmed 均不能代替这些条件。
243
+ 绑定/转移 completed 需要当前双方有效共识、指定 owner 和目标版本;TypeScript `confirm` 还核对本端明确同意,并按本端角色比较自己保存的 agent/owner 全文摘要。释放 completed 接受本任务声明 `v` 的新鲜 `released/v`,或由本任务原件严格关联的真实 `unbound/0` 完成证据;任务起始、目标版本保持 `v`;本次共识验收证据的 status/relation_version 保存真实 released/v 或 unbound/0,已有历史验收记录不改写。sub 离线或字段未清理不妨碍原 owner 以新鲜 released 完成,历史完成不替代当前关系检查。通知已发送、消息 ACK、ready、relation.confirmed 均不能代替这些条件。
242
244
 
243
245
  | 业务错误码 | 处理语义 |
244
246
  | --- | --- |
@@ -257,7 +259,7 @@ TypeScript 前六个方法返回 `Promise<OwnershipTaskResult>`,`checkOwnershi
257
259
 
258
260
  ## 9. P2P 载荷与实际收件拦截
259
261
 
260
- 控制载荷 type 固定为 `aun.ownership.sdk.v1`,必含 `operation_id/operation/action/sub_aid/owner_aid/base_relation_version/target_relation_version`;operation 为 bind/release/transfer;bind、transfer 的目标版本等于起始版本加一,release 的目标版本等于起始版本。transfer 必含 new_owner_aid,其它操作省略。reason 只允许在 reject 或 operation.stopped 中出现;未知、缺失字段拒绝。
262
+ 控制载荷 type 固定为 `aun.ownership.sdk.v1`,必含 `operation_id/operation/action/sub_aid/owner_aid/base_relation_version/target_relation_version`;operation 为 bind/release/transfer;bind、transfer 的目标版本等于起始版本加一,新任务 release 的目标版本等于起始版本,兼容旧 0.5.19 release 的原 base+1 wire 值而不改写原任务。transfer 必含 new_owner_aid,其它操作省略。reason 只允许在 reject 或 operation.stopped 中出现;未知、缺失字段拒绝。
261
263
 
262
264
  | action | 合法发送方向 |
263
265
  | --- | --- |
@@ -279,6 +281,38 @@ TypeScript 的拦截链为 [v2/e2ee/decrypt.ts](../../ts/src/v2/e2ee/decrypt.ts)
279
281
 
280
282
  [client/delivery.ts](../../ts/src/client/delivery.ts) 的 `publishOrderedQueueItem`、`publishPulledMessage` 等路径会等待 Client 事件拦截;移植时要检查实际 delivery 调用链,不能只为一个 handler 写正确代码却在其返回前 ACK。收件去重不要求网络恰好一次;重复或乱序提示回源后仅补尚未完成步骤,迟到消息不能改目标或重启拒绝/停止任务。
281
283
 
284
+ 下图展示普通有效控制消息的持久化边界。初次回源失败时,请求仍先进入 inbox,保存错误后等待恢复;`ownership.request` 只能在请求已核验并保存后发布。`sub.cleaned` 是额外前置校验分支:保存 inbox 前双读 NS,核对稳定的 `unbound/0`、空关系字段及前后相同的 ETag;回源失败或前后观察不一致时抛错,原投递队列保留消息、不推进游标、不 ACK;当前仍有关系时消费该提示而不推进清理。
285
+
286
+ ```mermaid
287
+ flowchart TD
288
+ A[push / pull / 重连 / 有序队列] --> B[解密:保留原 JSON 与已认证 from_aid]
289
+ B --> C{aun.ownership. 控制类型吗}
290
+ C -->|否| D[普通 message.received]
291
+ C -->|是| E{载荷词法、方向与固定任务上下文有效吗}
292
+ E -->|否或不支持的控制类型| F[消费控制消息,不作为聊天投递]
293
+ E -->|是| G[尝试新鲜读取 NS;按发送者、任务、action 去重]
294
+ G --> H[CAS 持久保存 inbox;存在性与存储失败分开]
295
+ H -->|保存失败| I[向调用链抛错:保留原队列与游标,不 ACK]
296
+ H -->|保存成功| J[processInbox 回源核验;失败保留已存待办]
297
+ J --> K{已核验的待审批请求吗}
298
+ K -->|是| L[持久记录核验结果后发布 ownership.request]
299
+ K -->|否| M[仅按已存审批推进文件、确认或清理]
300
+ L --> O[receive 成功返回:控制消息已处理或可靠保存]
301
+ M --> O
302
+ F --> O
303
+ O --> P[delivery 才可移除原消息、推进游标及 ACK]
304
+ ```
305
+
306
+ Client `_handleOwnershipMessage` 将已解密消息封套交给 Workflow 的关键片段如下。移植时保留原 JSON 文本;普通 JSON 对象已丢失重复键、整数词法时不能补做同等检查。
307
+
308
+ ```ts
309
+ const envelope = message as Record<string, unknown>;
310
+ const content = 'payload' in envelope ? envelope.payload : message;
311
+ return this._getOwnershipWorkflow().receive(
312
+ String(envelope.from_aid ?? ''), decryptedOwnershipJsonText(content) ?? content,
313
+ );
314
+ ```
315
+
282
316
  ## 10. 持久任务、审批与恢复
283
317
 
284
318
  ### 10.1 存储契约
@@ -304,6 +338,8 @@ TypeScript `AIDDatabase` 使用 `ownership_tasks(operation_id, revision, data)`
304
338
 
305
339
  ### 10.2 恢复顺序与失败重试
306
340
 
341
+ 0.5.20、0.5.19 及更早任务按原格式及原有协议边界兼容;保留原 operation、有效审批、原签名字节和原提交条件,不能因缺少后增本地字段而一律停止或新建任务。历史适配、绑定容错和无参数 reset 的完整范围见 [编排指南第 8 节](Ownership-SDK编排指南2.1.md#8-崩溃与响应丢失后的恢复)。reset 只归档当前身份发起的未完成任务,保留原记录和远端文件,迟到消息不能复活。 旧 Owner 候选尚未发布时,原 `expected_revision` 必须有权威证据精确匹配,不能用当前 version 替代;服务未提供旧 revision 证据时保留原件及任务并返回 unavailable。目标已提交但任务仍待恢复时,只有本地原始签名候选与当前双方共识精确匹配才确认完成;缺少这些证据不能从当前网络补造历史原件或提交条件。
342
+
307
343
  TypeScript `resume` 读取原任务,按 sub 串行 `drive`,实际顺序为 `processInbox → flush → 按分支 confirm/推进/清理`。`flush` 在发送每条待办前读取新鲜 NS,按 action 核对原关系或目标关系的完整声明、版本、锁和 owner;陈旧通知从 outbox 移除并持久保存,无法确认时保留待办,不发送。未完成任务的 transfer.ready 另核对持久授权期限。待审批请求重新发本地事件,仍为 pending;不能因为连接恢复或等待超时自动同意。通知发送本身不证明关系完成,后续处理和完成判断仍须核对新鲜 NS。
308
344
 
309
345
  | 中断位置 | 恢复依据和行为 |
@@ -322,6 +358,40 @@ TypeScript 的 `publishOwner` 固化起始存在性、完整原文和摘要,
322
358
 
323
359
  Client `_connectOnce` 通过 `_safeAsync(_resumeOwnershipAfterConnect())` 异步安排身份检查、注册意图和 Workflow 恢复。`await connect()` 不等于所有 Ownership 待办已经恢复完成;实现和应用应以对应结果/事件及 NS 新鲜事实判断。
324
360
 
361
+ 移植恢复入口应恢复原任务,不能用重新调用绑定/转移来代替。下图把本地故障、可重试依赖故障、确定冲突及完成后的待办分开。
362
+
363
+ ```mermaid
364
+ flowchart TD
365
+ A[重启或重连:读取并 decode 原任务] --> B{任务、审批、原件与完成证据完整吗}
366
+ B -->|否| P[persistence_unavailable:保留记录,停止副作用]
367
+ B -->|是| C[按 sub 串行:processInbox → flush → confirm / 推进 / 清理]
368
+ C --> D{新鲜权威结果及本人原件能确认本次目标吗}
369
+ D -->|能| E[CAS 保存 completed 与真实完成证据]
370
+ E --> F[按当前事实补有效通知、清理;失败仅留待办和错误]
371
+ D -->|依赖暂不可用| G[pending / retryable:保留任务、原字节和条件]
372
+ D -->|未提交目标| H{当前事实仍满足原声明、原件和条件吗}
373
+ H -->|否;目标未提交| I[conflict:stopped,不覆盖后续文件]
374
+ H -->|是| J{审批和授权状态}
375
+ J -->|未决定| K[重发 ownership.request,等待应用决定]
376
+ J -->|明确拒绝| L[rejected:不复活]
377
+ J -->|已同意且未过期| M[仅补未完成步骤,复用原任务、签名字节和原条件]
378
+ J -->|授权过期或撤回| I
379
+ C -. 确定材料无效 .-> N[invalid:error / false]
380
+ C -. 本地读写或 CAS 失败 .-> P
381
+ K --> G
382
+ M --> D
383
+ ```
384
+
385
+ 例如移植 `publishAgent` 时,下列顺序约束必须保留:先持久化完整签名文件,再通过原条件提交。片段省略本节及第 4~7 节规定的回源、原件、证书和目标材料校验,不能将它作为绕过这些校验的独立上传入口。
386
+
387
+ ```ts
388
+ task.files.agent = saved;
389
+ await task.persist();
390
+ const published = await this.deps.submitAgentMdRaw(
391
+ task.sub_aid, saved.raw, saved.condition,
392
+ );
393
+ ```
394
+
325
395
  ## 11. 三种流程与 self-owner
326
396
 
327
397
  | 流程 | 默认编排和最终依据 |
@@ -334,7 +404,108 @@ Client `_connectOnce` 通过 `_safeAsync(_resumeOwnershipAfterConnect())` 异步
334
404
 
335
405
  释放后的 sub 自动清理只使用本端明确 accept、包含 sub 角色、本人已签 agent 中 owner/sub/被释放的完整 statement(含 declaration_id、版本)完全匹配的原 bind/transfer 记录;转移历史匹配目标 owner。收到 release 通知时,因发布响应丢失仍 pending 的原任务也可提供该授权;无控制消息时,仅已完成历史任务的恢复路径触发自动清理,即使没有 relation.confirmed,也须新鲜核对权威释放事实。清理原件、全文摘要和原 CAS 单独持久保存,保持历史 completed 及原完成证据。字段已清空时不签写;响应丢失复用原件/条件,全文、ETag及已知提交 ETag 均对应原清理提交时只观察确认,冲突保留待办。没有该授权且仍有旧字段时,任务保持 pending 并发 action_required;acceptOwnershipRequest/rejectOwnershipRequest 不接受 release 任务,应用可通过已有名片 API 明确签署清理文件。
336
406
 
337
- 若新鲜有效名片的关系字段已经清空,sub 只有以本任务持久清理原件、摘要及原 CAS,或本人明确 accept 的匹配原 bind/transfer.release_cleanup,精确核对当前 NS 原文、摘要、ETag及已知提交 ETag 后,才可仅观察本任务清理完成,无需再签写或审批;空字段本身不证明本任务完成或本端同意。原 owner 的释放任务可早已 completed,历史绑定/转移 completed 也保持原记录;当前关系检查返回 `unbound`,响应版本为 `0`,任务版本仍为 `v`。NS 不保存释放终局或历史版本上界;后续绑定和旧任务恢复须重新核对完整文件与原条件。
407
+ ### 11.1 EC CLI 创建 sub 后,由 human owner 确认绑定
408
+
409
+ 以下是供 EC CLI 开发者接入的目标流程,EC CLI 当前尚未集成 Ownership。应用需在 Evolcore 一侧创建、加载 sub 身份,再由该 sub 调用 `bindOwneraid(ownerAid)`;先读取当前 agent.md 或确认其可靠不存在,再按原条件建立声明;不能覆盖已有关系或失败稿。sub 的主动发起已保存其同意,不需要没有 UI 的 sub 再交互确认;human owner 的 App 收到 `ownership.request` 后才展示确认。CLI 创建身份的具体命令属于上层应用,SDK 不定义 `ec` 命令。
410
+
411
+ ```mermaid
412
+ sequenceDiagram
413
+ participant EC as EC CLI / Evolcore(待接入)
414
+ participant S as sub SDK(无 UI)
415
+ participant O as human owner App / SDK
416
+ participant ST as owner Storage
417
+ participant NS as sub NS
418
+ EC->>S: 创建并加载 sub 身份
419
+ EC->>S: bindOwneraid(ownerAid)
420
+ S->>NS: 新鲜读取 agent.md 或可靠 404,核对基线及版本 v
421
+ S->>S: CAS 保存发起同意、原件和 outbox
422
+ S->>O: 加密 P2P bind.request
423
+ O->>O: inbox 持久化,回源核验后发 ownership.request
424
+ alt human 拒绝
425
+ O->>O: rejectOwnershipRequest;CAS 保存拒绝与回复
426
+ O->>S: bind.reject;双方结束审批,不写关系文件
427
+ else human 点击确认
428
+ O->>O: acceptOwnershipRequest;CAS 保存同意与回复
429
+ O->>S: bind.accept
430
+ O->>ST: declareSubaid:本人签署并原子发布 v+1 owner.md
431
+ O->>NS: SDK 后续推进/确认时新鲜检查
432
+ NS-->>O: sub 尚无匹配声明,不建立新锁
433
+ O->>S: owner.ready
434
+ S->>ST: 权威读取并验证目标 owner.md
435
+ S->>S: declareOwneraid:本人签署,保存原字节与原 CAS
436
+ S->>NS: 以 sub 身份条件 PUT agent.md
437
+ NS->>ST: 新鲜验证 owner 材料、证书与当前关系
438
+ NS->>NS: CAS 保存完整 agent.md,按原机制同步副本
439
+ S->>NS: 提交后再次新鲜检查
440
+ NS-->>S: 双文件共识成立,locked
441
+ S->>S: 新鲜确认共识及本人原件,保存 completed
442
+ S->>O: relation.confirmed
443
+ O->>O: 自行新鲜核查共识与本人原件后 completed
444
+ end
445
+ ```
446
+
447
+ 任一步骤遇到冲突、未知材料或服务失败,按第 10 节保留原任务或停止旧写入;`owner.ready`、消息 ACK 和图中通知均不替代新鲜共识。反向 `bindSubaid` 仍需要 sub 应用或策略明确审批;上述无人值守常规流程优先由 sub 发起。
448
+
449
+ ### 11.2 owner 释放与 sub 清理
450
+
451
+ ```mermaid
452
+ flowchart TD
453
+ A[原 owner 调用 releaseSubaid] --> B[新鲜确认本人旧关系 v;保存任务与原件]
454
+ B --> C[revokeSubaid:签署并原子发布同版本 release]
455
+ C --> D[新鲜读取两份权威材料,确认 released / v / unlocked]
456
+ D -->|无法确认| W[保留 release 与确认待办,恢复后重查]
457
+ W --> D
458
+ D -->|确认本任务| E[原 owner 保存 completed;sub 离线不阻碍]
459
+ E --> F[持久 outbox:relation.confirmed → sub]
460
+ F --> G[sub 回源确认释放;查找本人已同意的匹配原任务]
461
+ G --> H{有完整声明、原件和原 CAS 匹配的清理授权吗}
462
+ H -->|没有且仍有旧字段| I[pending;ownership.action_required;由应用明确签署清理]
463
+ H -->|有| J[revokeOwneraid:保存清理原件,以 sub 身份条件 PUT]
464
+ J --> K[NS 保存清理后的 agent.md:unbound / 0,并同步副本]
465
+ K --> L[sub.cleaned;owner 回源核对后更新清理进度]
466
+ E --> M[旧 release 延迟删除:先复核当前 NS 与本任务完整原件]
467
+ M -->|文件或当前关系已变化| N[停止旧删除,保留结果与待办]
468
+ ```
469
+
470
+ 有效权威不存在也可支持 `released/v`,但超时、无权限或普通下载 404 不属于权威不存在。若 sub 字段已清空,只能按第 10 节的本任务原件及提交证据观察确认,不能仅凭 `unbound/0` 认领完成;不再签写空字段。release 不属于可用 accept/reject 审批的任务。
471
+
472
+ ### 11.3 三方连续转移
473
+
474
+ ```mermaid
475
+ flowchart TD
476
+ A[原 owner:transferSubaid,保存原关系 v 与转移意图] --> B[持久并发送 transfer.request 给新 owner 和 sub]
477
+ B --> C[新 owner App:核验请求后明确同意或拒绝]
478
+ B --> D[sub 应用或明确配置的策略:核验后同意或拒绝]
479
+ C -->|拒绝| R[transfer.reject;停止未提交任务,原关系保持]
480
+ D -->|拒绝| R
481
+ C -->|同意| E[CAS 保存决定与 transfer.accept]
482
+ D -->|同意| F[CAS 保存决定与 transfer.accept]
483
+ E --> G{原 owner 收齐唯一参与 AID 的同意吗}
484
+ F --> G
485
+ G -->|未收齐| H[等待,不发布授权或目标文件]
486
+ G -->|已收齐| I[复核原件;固定期限及完整签名字节,先 CAS 持久化]
487
+ I --> J[transferOwneraid 发布旧版本授权;编排新鲜核查后发送 transfer.ready]
488
+ J --> K[新 owner 核对本端同意、授权目标、版本与未过期]
489
+ J --> L[sub 核对本端同意及授权,等待目标声明]
490
+ K --> M[declareSubaid:新 owner 自签原子发布 v+1 owner.md]
491
+ M --> N[新 owner 触发 NS 新鲜检查;owner.ready;sub 回源读取目标 owner.md]
492
+ L --> N
493
+ N --> O[declareOwneraid:sub 自签并保存原字节与原 CAS]
494
+ O --> P[以 sub 身份条件 PUT;NS 复核三方材料与期限]
495
+ P -->|通过| Q[CAS 保存目标关系文件 v+1;锁定新关系;sub 提交后新鲜回读]
496
+ P -->|不可确认或冲突| W[原任务保留或停止;不换原件、延期或 release 再 bind]
497
+ Q --> T[sub 新鲜确认目标与本人原件后 completed]
498
+ T --> U[relation.confirmed;各端自行回源确认后 completed]
499
+ U --> V[原 owner 复核当前 NS 及本任务完整旧原件后清理]
500
+ ```
501
+
502
+ sub 没有 UI 不表示默认同意所有转移;它仍须由应用或既有明确策略决定。授权期限仅限制新转移提交,过期本身不解除旧关系;已经提交的目标保持,通知或旧文件清理失败分别恢复。
503
+
504
+ ### 11.4 sub 的清理授权与 self-owner
505
+
506
+ 释放后的 sub 自动清理只使用本端明确 accept、包含 sub 角色且本人已签关系文件中 owner/sub/被释放的完整 statement(含 declaration_id、版本)完全匹配的原 bind/transfer 记录;转移历史匹配目标 owner。收到 release 通知时,因发布响应丢失仍 pending 的原任务也可提供该授权;无控制消息时,仅已完成历史任务的恢复路径触发自动清理,即使没有 relation.confirmed,也须新鲜核对权威释放事实。清理原件、全文摘要和原 CAS 单独持久保存,保持历史 completed 及原完成证据。字段已清空时不签写,可记录当前已清理的观察进度;Go SubCleaned 也可表示这一观察,单独不能证明本任务执行清理或首次完成 release,后者仍须第 10.1 节的原件关联证据。响应丢失复用原件/条件,全文、ETag及已知提交 ETag 均对应原清理提交时只观察确认,冲突保留待办。没有该授权且仍有旧字段时,任务保持 pending 并发 action_required;acceptOwnershipRequest/rejectOwnershipRequest 不接受 release 任务,应用需明确关系资源的清理意愿;应用可按既有名片 API 明确自签清理,仍须核验释放事实及原 CAS。
507
+
508
+ 若新鲜有效关系文件的关系字段已经清空,sub 只有以本任务持久清理原件、摘要及原 CAS,或本人明确 accept 的匹配原 bind/transfer.release_cleanup,精确核对当前 NS 原文、摘要、ETag及已知提交 ETag 后,才可仅观察本任务清理完成,无需再签写或审批;空字段本身不证明本任务完成或本端同意。原 owner 的释放任务可早已 completed,历史绑定/转移 completed 也保持原记录;当前关系检查返回 `unbound`,响应版本为 `0`,任务版本仍为 `v`。NS 不保存释放终局或历史版本上界;后续绑定和旧任务恢复须重新核对完整文件与原条件。
338
509
 
339
510
  self-owner 为 owner_aid 等于 sub_aid,同一身份按两个角色分别签自己的 owner.md 和 agent.md;不减少文件、签名或 NS 验收要求,不添加特殊状态。应用本端发起可覆盖本端角色意愿,SDK 不向自己发 P2P;转移中 sub 与新 owner 重合时合并对同一 AID 的请求和决定。
340
511
 
@@ -348,7 +519,7 @@ self-owner → 外部 owner 仍需当前身份的原 owner 授权及目标 agent
348
519
 
349
520
  普通名片候选先通过本地 schema/外层签名验证,在首次远端 preflight 前独立持久保存私有 `local_draft_content`;不覆盖远端 content/ETag。持有本地私钥的自有身份默认 resolve 优先该稿,返回 unverified、in_sync=false、source.agent_md_fetched=false;显式 download/forceRefresh 仍读取远端权威内容并保留草稿,服务端确认对应候选提交成功后才清稿。失败稿仅本地保留,普通 initial 失败稿同样需要应用显式重试;重连即使发现普通 pending 也不自动重传。`AgentMdManager._uploadPrepared` 取得可靠 NS 条件后,仍在 PUT 前持久保存 signedContent、pending_condition 和 pending_relation(原 owner、完整 statement、relation_version、lock)。显式重试既有 pending 时,`resumePendingUpload` **先检查持久原条件,再读取远端**;缺条件保留原元数据及原错误,即使远端同字节也不清待办。2.1 正文更新核对原版本、锁、owner 和完整 statement;受限 legacy 正文更新另保存可信 base 全文、摘要、原 ETag 及全部旧关系快照,核对 base/candidate/remote 的存在性、类型和值,缺上下文不得补造。当前原文与提交 ETag 均对应原提交时只观察确认,否则仅在原 CAS 和关系仍匹配时重传原 blob,不换条件或重签;关系改变、远端消失或已被 2.1 接管则冲突并保留 pending。其它缺原上下文的旧待办仅允许版本 0/unlocked 的初始关系;Ownership 2.1 任务、消息及 outbox 仍由其既有机制恢复。
350
521
 
351
- Group/Org 名片失败稿及 pending 保留实体命名空间中的完整多签原文、原 CAS、固定 owner 和实体证书指纹,由应用显式重试,post-connect/重连不隐式 PUT。重试先验证完整原件及当前 owner、状态和证书代际,原条件完整且同代际原文/ETag 已确认提交时只观察完成。转移、rekey 或解散后停止旧代际待办,不更换身份、指纹或条件重签。取消实体 V2 授权后,不再保存、刷新或检查其额外授权及过期窗口;普通文件签名与当前证书检查保留。专属 create/transfer 自身 checkpoint 恢复机制不变。
522
+ Group/Org 名片失败稿及 pending 保留实体命名空间中的完整多签原文、原 CAS、固定 owner 和实体证书指纹,由应用显式重试,post-connect/重连不隐式 PUT。重试先验证完整原件及当前 owner、状态和证书代际,原条件完整且同代际原文/ETag 已确认提交时只观察完成。转移、rekey 或解散后停止旧代际待办,不更换身份、指纹或条件重签。新 SDK 现代上传不再保存、刷新或检查额外 V2 授权及过期窗口;旧 V2 兼容入口仍按协议 §2.5 校验;普通文件签名与当前证书检查保留。专属 create/transfer 自身 checkpoint 恢复机制不变。
352
523
 
353
524
  普通主体注册指定 owner 时,[aid-store.ts](../../ts/src/aid-store.ts) 先保存 `protocol=2.1` 的 registration_intent 和固定 operation_id;可靠初始化只发布本人无 owner 名片。初次连接由 `_resumeRegistrationIntent` 复用同一 operation_id 进入绑定,注册成功不是关系已成立。Group/Org 的身份准备由专属生命周期使用,不建立通用注册 owner 意图;已有关系/不可靠读取不能作为重新初始化或清空关系的依据。
354
525