@agentunion/fastaun 0.5.28 → 0.5.29
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 +19 -0
- package/_packed_docs/CHANGELOG.md +19 -0
- package/_packed_docs/INDEX.md +9 -4
- package/_packed_docs/KITE_DOCS_GUIDE.md +4 -3
- package/_packed_docs/cli//345/207/255/350/257/201/344/270/216/347/273/204/347/273/207/346/234/215/345/212/241CLI/345/274/200/345/217/221/344/270/216/344/275/277/347/224/250/346/214/207/345/215/227.md +869 -0
- package/_packed_docs/sdk/0.5.27-SDK/345/272/224/347/224/250/351/233/206/346/210/220/346/214/207/345/215/227.md +408 -0
- package/_packed_docs/sdk/0.5.27-SDK/345/274/200/345/217/221/344/270/216/347/247/273/346/244/215/346/214/207/345/215/227.md +410 -0
- package/_packed_docs/sdk/0.5.28-SDK/345/272/224/347/224/250/351/233/206/346/210/220/346/214/207/345/215/227.md +228 -0
- package/_packed_docs/sdk/0.5.28-SDK/345/274/200/345/217/221/344/270/216/347/247/273/346/244/215/346/214/207/345/215/227.md +146 -0
- package/_packed_docs/sdk/0.5.29-SDK/345/272/224/347/224/250/351/233/206/346/210/220/346/214/207/345/215/227.md +180 -0
- package/_packed_docs/sdk/0.5.29-SDK/345/274/200/345/217/221/344/270/216/347/247/273/346/244/215/346/214/207/345/215/227.md +164 -0
- 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 -90
- package/_packed_docs/sdk/AUN_DOCS_GUIDE.md +5 -3
- package/_packed_docs/sdk/INDEX.md +12 -4
- 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
- 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 +1 -1
- package/_packed_docs//346/216/247/345/210/266/346/266/210/346/201/257/344/270/216/350/256/276/345/244/207/350/203/275/345/212/233/345/215/217/345/225/206/346/226/271/346/241/210.md +426 -0
- package/_packed_docs//346/266/210/346/201/257/345/220/214/346/255/245/344/270/216/345/216/206/345/217/262/346/213/211/345/217/226/344/273/243/347/240/201/345/256/241/346/237/245/351/227/256/351/242/230/346/270/205/345/215/225.md +279 -229
- package/_packed_docs//351/243/216/346/216/247/345/223/215/345/272/224/344/270/216SDK/345/215/217/345/220/214/346/226/271/346/241/210.md +381 -0
- package/dist/agent-md-changes.d.ts +2 -14
- package/dist/agent-md-changes.js +41 -212
- package/dist/agent-md-changes.js.map +1 -1
- package/dist/agent-md-schema.js +2 -2
- package/dist/agent-md-schema.js.map +1 -1
- package/dist/agent-md.d.ts +4 -6
- package/dist/agent-md.js +53 -53
- package/dist/agent-md.js.map +1 -1
- package/dist/aid-store.d.ts +3 -1
- package/dist/aid-store.js +61 -40
- package/dist/aid-store.js.map +1 -1
- package/dist/client/control-messages.js +28 -6
- package/dist/client/control-messages.js.map +1 -1
- package/dist/client/delivery.js +2 -1
- package/dist/client/delivery.js.map +1 -1
- package/dist/client/group-state.js +2 -3
- package/dist/client/group-state.js.map +1 -1
- package/dist/client/lifecycle.js +0 -2
- package/dist/client/lifecycle.js.map +1 -1
- package/dist/client/v2-e2ee.js +8 -4
- package/dist/client/v2-e2ee.js.map +1 -1
- package/dist/client.d.ts +2 -2
- package/dist/client.js +96 -46
- package/dist/client.js.map +1 -1
- package/dist/discovery.js +2 -1
- package/dist/discovery.js.map +1 -1
- package/dist/ownership-v21.d.ts +2 -1
- package/dist/ownership-v21.js +17 -3
- package/dist/ownership-v21.js.map +1 -1
- package/dist/ownership-workflow.js +9 -5
- package/dist/ownership-workflow.js.map +1 -1
- package/dist/semantic-facade.js +4 -2
- package/dist/semantic-facade.js.map +1 -1
- package/dist/semantic-protocol.js +2 -0
- package/dist/semantic-protocol.js.map +1 -1
- package/dist/tools/cross-sdk-agent.d.ts +1 -1
- package/dist/tools/cross-sdk-agent.js +16 -34
- package/dist/tools/cross-sdk-agent.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +8 -8
|
@@ -0,0 +1,410 @@
|
|
|
1
|
+
# AUN SDK 0.5.27 开发与移植指南
|
|
2
|
+
|
|
3
|
+
面向四 SDK 维护者与其它语言实现者,以 TS 接口说明协议、持久状态与适配边界。应用接线见[应用集成指南](0.5.27-SDK应用集成指南.md),完整凭证契约见[凭证与组织服务移植专题](凭证与组织服务SDK开发与移植指南.md)。
|
|
4
|
+
|
|
5
|
+
## 1. 版本基线与阅读方式
|
|
6
|
+
|
|
7
|
+
目标为截至 2026-10-29 的 `0.5.27` 工作区,功能基线为 `0.5.25` 源码提交 `133067c80`,包含中间提交和当前工作区增量。`0.5.26` 仅记录 TS npm 包的 `files` 白名单补入 `src/certs/root.crt`;运行时变化统一归入 `0.5.27`。
|
|
8
|
+
|
|
9
|
+
| 范围 | 本版对齐内容 |
|
|
10
|
+
| --- | --- |
|
|
11
|
+
| 凭证 | 普通结构化完整 Verify;语义/混合凭证、来源链、请求、证据与 Usage 材料 |
|
|
12
|
+
| 运行时 | 撤销同步、状态恢复、Gateway 迁移、当前态时间容错与心跳 |
|
|
13
|
+
| 实体与存储 | 组织首次名片/转让恢复、TS/Go/浏览器根证书初始化、IndexedDB 生命周期 |
|
|
14
|
+
| 验证边界 | 以源码及对应回归入口为准;已执行批次见 [parity 0.5.27](../../python/CHANGES_FOR_PARITY.md#v0527--相对于-v0525-基线的变更未发布) |
|
|
15
|
+
|
|
16
|
+
```mermaid
|
|
17
|
+
flowchart LR
|
|
18
|
+
A[协议字节和签名域] --> B[签验与状态机]
|
|
19
|
+
B --> C[Facade 和 RPC 映射]
|
|
20
|
+
C --> D[身份存储与传输适配]
|
|
21
|
+
D --> E[语言回归与场景验收]
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
下文 TS 片段按出现顺序共用以下声明;相对导入指向仓库源码。`declare` 表示宿主注入的输入或端口,其类型来自真实 SDK;业务示例在[应用指南](0.5.27-SDK应用集成指南.md)中展开。
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
import type { AUNClient } from '../../ts/src/client.js';
|
|
28
|
+
import type { CredentialSigner, CredentialVerificationContext } from '../../ts/src/org-protocol.js';
|
|
29
|
+
import type { SemanticPackageVerificationContext } from '../../ts/src/semantic-facade.js';
|
|
30
|
+
import type { EventPayload } from '../../ts/src/events.js';
|
|
31
|
+
import * as protocol from '../../ts/src/semantic-protocol.js';
|
|
32
|
+
declare const client: AUNClient;
|
|
33
|
+
declare const signer: CredentialSigner;
|
|
34
|
+
declare const trust: protocol.RecordVerificationContext;
|
|
35
|
+
declare const semanticServiceAid: string;
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## 2. 严格 JSON、签名字节与时间
|
|
39
|
+
|
|
40
|
+
### 2.1 原件与规范摘要
|
|
41
|
+
|
|
42
|
+
签名 JSON 使用 `SignedJsonBytes` 保留原字节;严格解析与结构校验拒绝重复键、不安全整数、孤立 surrogate 和非法字段。区分缺省与 `null`,保留数组顺序。语义 canonical JSON 按协议排序键、规范字符串及数字,摘要为 `sha256:<小写 hex>`。
|
|
43
|
+
|
|
44
|
+
```mermaid
|
|
45
|
+
flowchart LR
|
|
46
|
+
A[原始 JSON 字节] --> B[严格解析与结构校验]
|
|
47
|
+
B --> C[按对象规则生成签名字节]
|
|
48
|
+
C --> D[P-256 与 SHA-256 签验]
|
|
49
|
+
B --> E[规范摘要绑定原件与修订]
|
|
50
|
+
A --> F[保留 SignedJsonBytes]
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
declare const sourceBytes: Uint8Array;
|
|
55
|
+
const parsed = protocol.parseJsonStrict(sourceBytes);
|
|
56
|
+
const canonical = protocol.canonicalJson(parsed);
|
|
57
|
+
const objectHash = protocol.digest(parsed);
|
|
58
|
+
const rawHash = protocol.bytesDigest(sourceBytes);
|
|
59
|
+
const encodedCanonical = protocol.encodeSignedJson(parsed);
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
`objectHash` 是规范对象摘要,`rawHash` 是原字节摘要;`encodeSignedJson` 编码给定对象,保存外部原件时应直接保留收到的 `SignedJsonBytes`。普通 CAP 与组织外层 `client_signature` 的 canonical 规则分层沿用,见[共同密码学规则](凭证与组织服务SDK开发与移植指南.md#2-共同密码学和-json-规则)。
|
|
63
|
+
|
|
64
|
+
### 2.2 签名域与证书端口
|
|
65
|
+
|
|
66
|
+
十一签名域分别为 semantic-credential、registration-metadata、registration-receipt、credential-status、usage-allocation、allocation-status、semantic-crl、usage-transition、usage-checkpoint、usage-acceptance、ledger-abort。签名为 ECDSA P-256/SHA-256、标准 Base64 的 ASN.1 DER;浏览器 WebCrypto 适配负责签名格式转换。
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
declare const semanticDraft: Parameters<typeof client.credential.signCredential>[0];
|
|
70
|
+
const signedOriginal = await client.credential.signCredential(semanticDraft, signer);
|
|
71
|
+
const originalReport = await client.credential.verifyOriginal(signedOriginal, {
|
|
72
|
+
...trust, expectedAid: signer.aid,
|
|
73
|
+
});
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
证书 resolver 按指纹、AID 与签署时点取材料,trust verifier 校验可信链与身份。当前态资格使用 ±300 秒容错;历史签署时点、本地签名资格按证书原始有效期检查。声明最大生命周期、单调耗时与缓存 TTL 各自执行。
|
|
77
|
+
|
|
78
|
+
```ts
|
|
79
|
+
declare const nbf: number;
|
|
80
|
+
declare const exp: number | null;
|
|
81
|
+
const now = Math.trunc(Date.now() / 1000);
|
|
82
|
+
protocol.validateWindow(nbf, exp, now);
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## 3. 普通结构化凭证
|
|
86
|
+
|
|
87
|
+
`aun-cap/1` 继续使用原创建、登记、状态、撤销及完整 Verify。根深度为 0,子凭证递增,最大委托深度 8;各层受众、时间、能力及约束收窄。混合来源链中的普通层通过可信 `legacyVerifier` 复用此路径。
|
|
88
|
+
|
|
89
|
+
```mermaid
|
|
90
|
+
flowchart TD
|
|
91
|
+
A[异步预载可信证书和当前状态] --> B[建立同步只读 resolver]
|
|
92
|
+
B --> C[结构与逐层签名及委托链]
|
|
93
|
+
C --> D[实际能力和约束]
|
|
94
|
+
D --> E[实际请求绑定]
|
|
95
|
+
E --> F[成员及代表的当前材料]
|
|
96
|
+
F --> G[重查有效窗口并返回结果]
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
```ts
|
|
100
|
+
declare const ordinaryOptions: Parameters<typeof client.credential.create>[0];
|
|
101
|
+
const ordinaryCredential = client.credential.create(ordinaryOptions, signer);
|
|
102
|
+
declare const ordinaryContext: CredentialVerificationContext;
|
|
103
|
+
const ordinarySignature = client.credential.verifySignature(
|
|
104
|
+
ordinaryCredential, ordinaryContext.resolveCertificate,
|
|
105
|
+
ordinaryContext.now, ordinaryContext.audience,
|
|
106
|
+
);
|
|
107
|
+
const ordinaryVerified = client.credential.verify(ordinaryCredential, ordinaryContext);
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
TS 的普通 `verify` 为同步调用。`ordinaryContext` 注入真实 audience、subject、能力与约束,以及 method/target/params/requestId/nonce/requestBinding。成员及代表场景还接当前成员、Ownership 与 actor 状态;异步网络取材在调用前完成。具体端口见[同步完整 Verify](凭证与组织服务SDK开发与移植指南.md#34-同步完整-verify-与约束端口)。
|
|
111
|
+
|
|
112
|
+
```ts
|
|
113
|
+
declare const ordinaryReceipt: unknown;
|
|
114
|
+
declare const ordinaryRequest: Record<string, unknown>;
|
|
115
|
+
declare const ordinaryServiceAid: string;
|
|
116
|
+
client.credential.verifyRegistrationReceipt(
|
|
117
|
+
ordinaryReceipt, ordinaryCredential, ordinaryRequest,
|
|
118
|
+
ordinaryContext.resolveCertificate, ordinaryServiceAid, ordinaryContext.now,
|
|
119
|
+
);
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
普通状态证明须验服务身份、签名、CID、当前态、窗口与请求挑战,再供同步 resolver 使用;CRL 验完整分页后原子保存事件与游标。适配见[普通状态证明](凭证与组织服务SDK开发与移植指南.md#65-普通状态证明的可信适配)、[普通 CRL](凭证与组织服务SDK开发与移植指南.md#66-普通-crl-分页与原子持久)。
|
|
123
|
+
|
|
124
|
+
## 4. 语义与混合凭证
|
|
125
|
+
|
|
126
|
+
### 4.1 模式与管理调用
|
|
127
|
+
|
|
128
|
+
| 模式 | 授权材料 |
|
|
129
|
+
| --- | --- |
|
|
130
|
+
| 纯语义 `aun-cap/semantic-1`、`cap=[]` | 原件、确认元数据、正文及业务策略 |
|
|
131
|
+
| 混合 `aun-cap/semantic-1`、非空 `cap` | 结构化能力与语义限制共同验收,逐层取交集 |
|
|
132
|
+
| 混合来源链 | 普通层完整 Verify,加语义层原件/元数据/回执/当前态验证 |
|
|
133
|
+
|
|
134
|
+
六个 RPC 为 `credential.semantic.register/get/status/revise/revoke/revocationList`。`client.credential` 平铺这些能力;普通同名方法按语义字段分流。跨域 TS/JS 使用第二参数 `{serviceAid}`,Python 使用 `target=`,Go 通过目标 Facade 与 context 调用。
|
|
135
|
+
|
|
136
|
+
```mermaid
|
|
137
|
+
flowchart LR
|
|
138
|
+
A[原件与确认元数据分别签名] --> B[Facade 生成管理 binding]
|
|
139
|
+
B --> C[六个 semantic RPC]
|
|
140
|
+
C --> D[逐项校验原件和修订及服务回执]
|
|
141
|
+
D --> E[按权威与受众保存观察状态]
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
```ts
|
|
145
|
+
declare const registerInput: protocol.SemanticFacadeInput<protocol.SemanticRegisterParams>;
|
|
146
|
+
const registered = await client.credential.register(registerInput, {
|
|
147
|
+
serviceAid: semanticServiceAid,
|
|
148
|
+
});
|
|
149
|
+
declare const reviseInput: protocol.SemanticFacadeInput<protocol.SemanticReviseParams>;
|
|
150
|
+
const revised = await client.credential.revise(reviseInput, {
|
|
151
|
+
serviceAid: semanticServiceAid,
|
|
152
|
+
});
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Facade 输入省略 `request_binding`,由 SDK 绑定实际 method、target、参数摘要、CID、request_id、nonce 与时间。low-level 使用完整 wire;幂等重试沿原 request_id 和同一意图,错误保留 `data.error_code`、`retryable` 及状态材料。
|
|
156
|
+
|
|
157
|
+
```ts
|
|
158
|
+
const registerWire: protocol.SemanticRegisterParams = {
|
|
159
|
+
...registerInput,
|
|
160
|
+
request_binding: protocol.buildManagementBinding(
|
|
161
|
+
'credential.semantic.register', semanticServiceAid, registerInput,
|
|
162
|
+
),
|
|
163
|
+
};
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### 4.2 来源链、认证请求与业务决策
|
|
167
|
+
|
|
168
|
+
```mermaid
|
|
169
|
+
flowchart TD
|
|
170
|
+
A[根到叶的来源链] --> B[buildPackage 校验结构和上下界]
|
|
171
|
+
B --> C[verifyPackage 验签及当前态]
|
|
172
|
+
C --> D[verifyRequest 绑定认证 actor 与实际服务]
|
|
173
|
+
D --> E[逐层正文及结构化能力交集]
|
|
174
|
+
E --> F[事实和策略生成 DecisionInput]
|
|
175
|
+
F --> G[宿主完成业务接受及原子执行]
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
```ts
|
|
179
|
+
declare const lineage: protocol.CredentialLineageEntry[];
|
|
180
|
+
declare const packageContext: SemanticPackageVerificationContext;
|
|
181
|
+
const grant = await client.credential.buildPackage(lineage);
|
|
182
|
+
const packageReport = await client.credential.verifyPackage(grant, packageContext);
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
`packageContext` 提供真实 audience、签发者与可信 resolver;跨域以 `serviceFor(cid)` 指定各层权威,普通层提供 `legacyVerifier`。online 模式还传各 CID 的 query 及实际单调耗时。`checked` 与 `required` 分别列出已验项目和宿主待完成项目。
|
|
186
|
+
|
|
187
|
+
```ts
|
|
188
|
+
declare const requestInput: Parameters<typeof client.credential.buildRequest>[0];
|
|
189
|
+
declare const authentication: protocol.AuthenticatedAUNContext;
|
|
190
|
+
declare const requestOptions: Parameters<typeof client.credential.verifyRequest>[2];
|
|
191
|
+
const request = await client.credential.buildRequest(requestInput);
|
|
192
|
+
const requestReport = await client.credential.verifyRequest(
|
|
193
|
+
request, authentication, requestOptions,
|
|
194
|
+
);
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
发送端请求有效期为当前时刻之后、最长 300 秒;接收端调用 SDK 时间校验。认证 actor、服务、subject 与代表关系取自当前认证和可信材料,参数与来源链摘要绑定同一请求。
|
|
198
|
+
|
|
199
|
+
```ts
|
|
200
|
+
declare const bodies: protocol.VerifiedBody[];
|
|
201
|
+
declare const facts: protocol.JsonObject;
|
|
202
|
+
declare const policy: protocol.PolicyRef;
|
|
203
|
+
const decisionInput = await client.credential.buildDecisionInput(
|
|
204
|
+
request, bodies, facts, policy,
|
|
205
|
+
);
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
模型返回 allow/deny/indeterminate;宿主按策略验引用、事实有效期、后置条件及额度,再形成执行回执。`verifyRequest` 与 `verifyPackage` 的验真结果分别供这些步骤使用。
|
|
209
|
+
|
|
210
|
+
### 4.3 状态、CRL 与冷恢复
|
|
211
|
+
|
|
212
|
+
online 状态及 allocation 查询的本地单调耗时严格小于 30 秒,绑定本次 request_hash/nonce;bounded 最大陈旧度为 300 秒。消费 TTL 直接比较单调耗时;当前态 ±300 秒容错不延长消费期限。
|
|
213
|
+
|
|
214
|
+
```mermaid
|
|
215
|
+
flowchart TD
|
|
216
|
+
A[按权威和 CID 及受众读取本地观察] --> B[查询绑定当前修订和策略]
|
|
217
|
+
B --> C[验签及 challenge 和时间]
|
|
218
|
+
C --> D[核对 state_seq 与已观察终态]
|
|
219
|
+
D --> E[原子保存状态或完整 CRL 页和游标]
|
|
220
|
+
E --> F[消费前再校验 TTL]
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
```ts
|
|
224
|
+
declare const statusInput: protocol.SemanticFacadeInput<protocol.SemanticStatusParams>;
|
|
225
|
+
const proof = await client.credential.status(statusInput, {
|
|
226
|
+
serviceAid: semanticServiceAid,
|
|
227
|
+
});
|
|
228
|
+
declare const crlInput: protocol.SemanticFacadeInput<protocol.SemanticRevocationListParams>;
|
|
229
|
+
const crlPage = await client.credential.revocations(crlInput, {
|
|
230
|
+
serviceAid: semanticServiceAid,
|
|
231
|
+
});
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
CRL 按 authority、CID、audience/scope 隔离,整页验真后保存事件与游标。普通分页以 `''` 结束,语义分页以 `null` 结束。普通长连接认证/重连后立即 fresh 同步撤销,之后按小时补拉;short 跳过后台扫描,Python fresh 贯通各页。
|
|
235
|
+
|
|
236
|
+
| 持久项 | metadata key |
|
|
237
|
+
| --- | --- |
|
|
238
|
+
| 普通撤销快照 | `credential_revocations_v1` |
|
|
239
|
+
| Python 语义状态 | `semantic_credential_state_v1` |
|
|
240
|
+
| TS 语义状态 | `semantic_credentials_v1` |
|
|
241
|
+
| JS 语义状态 | `semantic_credential_state_v1` |
|
|
242
|
+
| Go 语义状态 | `semantic_revocations_v1` |
|
|
243
|
+
|
|
244
|
+
保存已观察状态序号、撤销、scope 游标、请求/nonce 绑定与 allocation 状态。身份、设备、slot 及连接代际隔离异步结果;重建 Facade 后,旧证明须重新取得有效本地计时依据。移植时对应各端已有状态适配,不将单调计时起点当跨进程时间戳保存。
|
|
245
|
+
|
|
246
|
+
### 4.4 消息证据
|
|
247
|
+
|
|
248
|
+
```mermaid
|
|
249
|
+
flowchart LR
|
|
250
|
+
A[原始加密信封和明文字节] --> B[归档与 EvidenceRef]
|
|
251
|
+
B --> C[原收件身份与密钥]
|
|
252
|
+
C --> D[历史发送者证书和签名]
|
|
253
|
+
D --> E[群 epoch 及收件 Merkle 证明]
|
|
254
|
+
E --> F[VerifiedBody 与正文摘要]
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
```ts
|
|
258
|
+
declare const envelopeBytes: Uint8Array;
|
|
259
|
+
declare const received: Parameters<typeof client.credential.archiveMessage>[1];
|
|
260
|
+
const archive = await client.credential.archiveMessage(envelopeBytes, received);
|
|
261
|
+
const envelopeRef = await client.credential.createEvidenceRef(
|
|
262
|
+
envelopeBytes, 'aun-e2ee-v2-envelope-raw/1',
|
|
263
|
+
);
|
|
264
|
+
declare const messageContext: protocol.SemanticMessageVerificationContext;
|
|
265
|
+
const body = await client.credential.verifyMessageBody(signedOriginal, messageContext);
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
实时消息的 `_semantic_evidence` 保留原 envelope/payload 字节;`message_ref` 验证使用可信解析器、原签署时间和证书指纹、原收件身份及群收件证明。附件按原摘要解析,资源定位见[消息证据适配](凭证与组织服务SDK开发与移植指南.md#45-消息证据适配)。
|
|
269
|
+
|
|
270
|
+
### 4.5 UsageRef 与账本协调
|
|
271
|
+
|
|
272
|
+
```mermaid
|
|
273
|
+
flowchart TD
|
|
274
|
+
A[已验凭证和 UsageContract] --> B[可信 allocation 与在线状态]
|
|
275
|
+
B --> C[宿主预留并执行]
|
|
276
|
+
C --> D{结果}
|
|
277
|
+
D -->|明确成功或失败| E[宿主原子结算]
|
|
278
|
+
D -->|unknown| F[按原 request_id 核对]
|
|
279
|
+
F --> E
|
|
280
|
+
E --> G[保存执行回执]
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
`prepareUsage/commitUsage/abortUsage` 分别映射 `revise` 的 usage_prepare/usage_commit/usage_abort,返回 `UsageTransitionReceipt`。候选修订、UsageRef、transition_id、fence、checkpoint、allocation closure 与 acceptance 保持同一协调关系。
|
|
284
|
+
|
|
285
|
+
```ts
|
|
286
|
+
declare const prepareInput: protocol.SemanticUsageInput<'usage_prepare'>;
|
|
287
|
+
const prepared = await client.credential.prepareUsage(prepareInput, {
|
|
288
|
+
serviceAid: semanticServiceAid,
|
|
289
|
+
});
|
|
290
|
+
declare const commitInput: protocol.SemanticUsageInput<'usage_commit'>;
|
|
291
|
+
const committed = await client.credential.commitUsage(commitInput, {
|
|
292
|
+
serviceAid: semanticServiceAid,
|
|
293
|
+
});
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
中断后用原 transition_id 查询协调状态,按返回结果继续 commit/abort;业务效果、预留、Unknown 核对和账本原子性由宿主负责。完整材料与恢复契约见[额度与 UsageRef](凭证与组织服务SDK开发与移植指南.md#48-额度与-usageref-切换)。
|
|
297
|
+
|
|
298
|
+
## 5. 组织实体、首次名片与转让恢复
|
|
299
|
+
|
|
300
|
+
组织成员保留双签 binding、成员 CAP、登记授权和服务回执;成员及代表当前态接入普通完整 Verify。组织身份操作使用本端高层编排,保存 checkpoint 后再推进后续阶段。
|
|
301
|
+
|
|
302
|
+
```mermaid
|
|
303
|
+
flowchart TD
|
|
304
|
+
A[创建组织并保存本次 active 结果] --> B[读取名片 authority]
|
|
305
|
+
B -->|已有投影| C[按当前权威与 CAS 更新]
|
|
306
|
+
B -->|HTTP 404| D[核对本次组织及当前 owner]
|
|
307
|
+
D --> E[fresh 获取实体证书并比对指纹]
|
|
308
|
+
E --> F[按初始条件上传名片]
|
|
309
|
+
C --> G[上传完成后清 creation checkpoint]
|
|
310
|
+
F --> G
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
```ts
|
|
314
|
+
import type { AIDStore } from '../../ts/src/aid-store.js';
|
|
315
|
+
declare const aidStore: AIDStore;
|
|
316
|
+
declare const orgCreateParams: Parameters<AUNClient['createOrg']>[0];
|
|
317
|
+
const organization = await client.createOrg(orgCreateParams, { aidStore });
|
|
318
|
+
declare const orgTransferParams: Parameters<AUNClient['completeOrgTransfer']>[0];
|
|
319
|
+
const transferredOrganization = await client.completeOrgTransfer(orgTransferParams, { aidStore });
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
初始 fallback 仅用于 NS 明确缺少投影且本次 org_id/owner_aid/active 状态匹配。完成转让还核对本次 transfer_id,采用已确认的新 owner 上下文;两条路径均 fresh 获取当前组织证书并核对指纹。
|
|
323
|
+
|
|
324
|
+
```mermaid
|
|
325
|
+
flowchart LR
|
|
326
|
+
A[验证双方成员材料] --> B[保存新密钥并 rekey]
|
|
327
|
+
B --> C[导入证书并替换成员凭证]
|
|
328
|
+
C --> D[finalize 转让]
|
|
329
|
+
D --> E[更新新 owner 名片]
|
|
330
|
+
E --> F[保存 completed 并清临时密钥]
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
重试原 pending 名片时核对当前身份、owner 与原 CAS 条件。TS 首次群名片同样使用本次返回证书和 owner 上下文。既有 Ownership 继续采用文件/NS 当次执行流程,通用消息、凭证与组织的 checkpoint 按各自职责保留。
|
|
334
|
+
|
|
335
|
+
## 6. Gateway 迁移与可靠交付
|
|
336
|
+
|
|
337
|
+
### 6.1 迁移状态与恢复顺序
|
|
338
|
+
|
|
339
|
+
协商 `gateway_migrate_v1` 后接收 `gateway.migrate`。通知核对 issuer、AID、device、slot、connection_id、递增 revision、migration_id,以及未来 300 秒内的有效期;目标为同 issuer 的 `wss:` 地址和 `/aun` 路径。
|
|
340
|
+
|
|
341
|
+
```mermaid
|
|
342
|
+
flowchart TD
|
|
343
|
+
A[ready 收到合法迁移通知] --> B[standby 并暂停新 RPC 与后台任务]
|
|
344
|
+
B --> C[最多排空 5 秒并保存已提交水位]
|
|
345
|
+
C --> D[关闭旧连接并清 inline ACK 状态]
|
|
346
|
+
D --> E[优先目标 Gateway 再认证]
|
|
347
|
+
E -->|失败且仍在期限内| F[fresh 发现并按配置退避]
|
|
348
|
+
F --> E
|
|
349
|
+
E -->|认证成功且连接有效| G[ready 解除门控]
|
|
350
|
+
G --> H[恢复后台任务和离线补拉]
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
```ts
|
|
354
|
+
declare const observeMigration: (payload: EventPayload) => void;
|
|
355
|
+
client.on('gateway.migrate', (payload) => {
|
|
356
|
+
observeMigration(payload);
|
|
357
|
+
});
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
迁移由 SDK 驱动,应用订阅事件观察进度。显式 connect/disconnect/close 接管或终止迁移;旧 transport、reader 与重连回调按代际隔离。迁移中调用沿现有错误类型返回,业务写操作沿原幂等键核对结果。
|
|
361
|
+
|
|
362
|
+
### 6.2 交付提交与心跳
|
|
363
|
+
|
|
364
|
+
```mermaid
|
|
365
|
+
flowchart LR
|
|
366
|
+
A[收页并验证覆盖证明] --> B[释放网络 Gate]
|
|
367
|
+
B --> C[解密和内部协议处理]
|
|
368
|
+
C --> D[等待应用处理器事务]
|
|
369
|
+
D --> E[复核身份代际并可靠保存水位]
|
|
370
|
+
E --> F[仅 ACK 已提交前缀]
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
```ts
|
|
374
|
+
declare const commitBatch: (payload: EventPayload) => Promise<void>;
|
|
375
|
+
client.on('message.batch', async (batch) => {
|
|
376
|
+
await commitBatch(batch);
|
|
377
|
+
});
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
宿主事务须可重放;处理器 Promise 完成才推进提交水位。网络 Gate 按页释放,应用处理及退避独立;batch/single 每页固定,保留 peer namespace、容量、覆盖证明及已提交前缀契约,见[0.5.24 可靠交付](0.5.24-SDK开发与移植指南.md#3-peer-同步batch持久提交与退避)。
|
|
381
|
+
|
|
382
|
+
Python、Node TS、Go 结合入站活跃度处理心跳。Node 每 30 秒 Ping,10 秒静默超时,连续三次静默超时终止连接;Pong 或普通消息清零,Ping 错误立即终止。浏览器依赖宿主 WebSocket 生命周期。
|
|
383
|
+
|
|
384
|
+
## 7. 存储、信任根与语言适配
|
|
385
|
+
|
|
386
|
+
| 端 | 0.5.27 实现要求 |
|
|
387
|
+
| --- | --- |
|
|
388
|
+
| TS Node | LocalIdentityStore/LocalTokenStore 初始化时排他补入缺失内置根,保留已有根;npm 打包白名单与运行时初始化分别验收 |
|
|
389
|
+
| Go | AuthFlow 用内置根初始化空信任目录,保留已有本地根配置 |
|
|
390
|
+
| JS 浏览器 | IndexedDB 初始化事务提交后发布 DB;versionchange/close 隔离旧 open promise;缺少时补内置根 |
|
|
391
|
+
| JS 查询缓存 | 缓存键移除本地 signAs/sign_as,发往 loader 的参数保持原值 |
|
|
392
|
+
| Python | 名片下载从持久 load_record 取得当前观察;普通撤销 fresh 标记贯通分页 |
|
|
393
|
+
|
|
394
|
+
文件端采用路径与文件事务适配,浏览器采用 IndexedDB/WebCrypto;四端共享协议和 wire。公开异步约定保持 Python async、TS/JS Promise、Go context/error。外部地址使用 `{svc}.{issuer}`,如 `credential.agentid.cn`。
|
|
395
|
+
|
|
396
|
+
## 8. 回归与场景对照
|
|
397
|
+
|
|
398
|
+
按协议向量、Facade、持久恢复、真实场景顺序验收;执行测试首失败停止,修复后从该用例继续。以下为入口清单,实际通过范围以各批记录为准。
|
|
399
|
+
|
|
400
|
+
| 契约 | 源码/回归入口 |
|
|
401
|
+
| --- | --- |
|
|
402
|
+
| 严格 JSON、签名及时间 | [TS 协议](../../ts/src/semantic-protocol.ts)、[协议测试](../../ts/tests/conformance/semantic_protocol.test.ts) |
|
|
403
|
+
| 语义管理、状态及恢复 | [TS Facade](../../ts/src/semantic-facade.ts)、[Facade 测试](../../ts/tests/unit/semantic-facade.test.ts) |
|
|
404
|
+
| 普通 Verify、成员及代表 | [org-protocol](../../ts/src/org-protocol.ts)、[组织测试](../../ts/tests/unit/org-facade.test.ts) |
|
|
405
|
+
| 迁移、可靠交付及实体编排 | [client](../../ts/src/client.ts)、[client 测试](../../ts/tests/unit/client.test.ts)、[transport 测试](../../ts/tests/unit/transport.test.ts) |
|
|
406
|
+
| 四端共同场景 | [场景清单](../../examples/semantic-credential/scenarios.json)、[示例说明](../../examples/semantic-credential/示例使用指南.md)、[跨 SDK 运行器](../../tests/cross-sdk/runner/run_cross_sdk_e2e.py) |
|
|
407
|
+
| 宿主账本与 Unknown | [参考账本](../../examples/semantic-credential/reference-host/ledger.py)、[宿主实现](../../examples/semantic-credential/reference-host/host.py) |
|
|
408
|
+
| CLI 与协议接口 | [CLI 专题](../cli/凭证与组织服务CLI开发与使用指南.md)、[凭证 RPC](09-凭证服务RPC手册.md)、[组织 RPC](09-组织服务RPC手册.md) |
|
|
409
|
+
|
|
410
|
+
功能增量与各语言差异按 [parity 0.5.27](../../python/CHANGES_FOR_PARITY.md#v0527--相对于-v0525-基线的变更未发布)逐项对齐。本次专题整理采用静态文档与示例校验,发布包验收使用相应版本产物另记执行结果。
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
# AUN SDK 0.5.28 应用集成指南
|
|
2
|
+
|
|
3
|
+
本文面向 TypeScript SDK 应用开发者,整理 `@agentunion/fastaun` 0.5.28 未发布工作区的完整接入主线。SDK 实现与适配边界见[0.5.28 SDK 开发与移植指南](0.5.28-SDK开发与移植指南.md);四端增量和验证边界见 [parity 0.5.28](../../python/CHANGES_FOR_PARITY.md#v0528--校验控制消息与风控未发布)。0.5.27 指南保留为历史版本。
|
|
4
|
+
|
|
5
|
+
## 1. 版本范围与接入路径
|
|
6
|
+
|
|
7
|
+
0.5.28 在 0.5.27 应用流程上增加方向区分的 `agent.md` schema 校验、普通共识查询的单次 fresh 复核、分类消息、Owner 名片变更通知和风控响应。该版本尚未发布;应用应按实际安装包和服务端能力验收。
|
|
8
|
+
|
|
9
|
+
| 范围 | SDK 行为 | 应用职责 |
|
|
10
|
+
| --- | --- | --- |
|
|
11
|
+
| 身份与连接 | 管理身份材料、会话、消息拉取与重连 | 持久保存身份目录和 seed;先安装事件处理器再连接 |
|
|
12
|
+
| 消息 | 解密、分类、交付、游标与 ACK 恢复 | 原子持久化业务消息,按业务键幂等处理 |
|
|
13
|
+
| 凭证 | 提供签验、当前状态和请求绑定 API | 注入可信身份、实际请求上下文、业务授权和事务 |
|
|
14
|
+
| Ownership | 校验文件和 NS 共识,支持一次 fresh 重查 | 审批前执行业务授权;按共识结果决定是否共享 |
|
|
15
|
+
| Owner 名片通知 | 持久重试通知、下载验签并可靠发布变更事件 | 将事件接入业务索引或缓存更新,并持久完成应用工作 |
|
|
16
|
+
| 风控 | 执行已验签策略、请求门控、ACK 与状态通知 | 处理受限状态和原请求结果未知,不绕过服务端限制 |
|
|
17
|
+
|
|
18
|
+
## 2. 身份、信任根与连接
|
|
19
|
+
|
|
20
|
+
Node.js 运行时要求 Node `>=22.16.0`。身份目录、加密 seed、设备和 slot 应在重启后保持稳定;切换应用用户或隔离环境时使用独立目录与 slot。示例使用应用已经安全取得的身份,不在代码中生成或伪造身份材料。
|
|
21
|
+
|
|
22
|
+
```ts
|
|
23
|
+
import { AIDStore, AUNClient } from '@agentunion/fastaun';
|
|
24
|
+
const store = new AIDStore({ aunPath: process.env.AUN_PATH!,
|
|
25
|
+
encryptionSeed: process.env.AUN_SEED ?? '', slotId: 'main', verifySsl: true });
|
|
26
|
+
const loaded = store.load(process.env.AUN_AID!);
|
|
27
|
+
if (!loaded.ok) throw new Error(loaded.error.message);
|
|
28
|
+
const signer = loaded.data.aid;
|
|
29
|
+
if (!signer.isPrivateKeyValid()) throw new Error('身份私钥不可用');
|
|
30
|
+
const client = new AUNClient(signer);
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
文件 store 缺少 SDK 内置根证书时会补入内置根并保留已有本地根。应用自己的额外信任根和证书链仍须按业务信任策略管理。首次注册走 `store.register()`;已有身份在启动时重新加载,不应因普通重连重新创建身份。
|
|
34
|
+
|
|
35
|
+
### 2.1 先订阅,再连接
|
|
36
|
+
|
|
37
|
+
为避免积压消息先于应用处理器到达,在连接前注册需要的事件。业务 handler 返回的 Promise 应在业务持久化成功后完成。
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
declare function commitBatch(batch: unknown): Promise<void>;
|
|
41
|
+
client.on('message.batch', commitBatch);
|
|
42
|
+
client.on('group.message_batch', commitBatch);
|
|
43
|
+
client.on('group.event_batch', commitBatch);
|
|
44
|
+
client.on('state_change', () => updateConnectionView(client.state));
|
|
45
|
+
await client.connect({ auto_reconnect: true });
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
SDK 的连接就绪、消息追赶和业务事务是不同状态。界面可以展示连接状态,但业务处理只有在对应应用事务成功后才算完成。
|
|
49
|
+
|
|
50
|
+
### 2.2 浏览器运行时
|
|
51
|
+
|
|
52
|
+
浏览器使用 `@agentunion/fastaun-browser`。身份、token 和 checkpoint 保存到 IndexedDB,密码运算由 WebCrypto 完成,HTTPS 证书信任由浏览器控制。浏览器同样应先注册消息处理器再连接;Node 文件 store 的目录和 seed 配置不可直接套用到浏览器。
|
|
53
|
+
|
|
54
|
+
## 3. 消息交付与分类控制流
|
|
55
|
+
|
|
56
|
+
普通消息通过 Push 与 Pull 合并收取。SDK 解密并交付 batch 后,等待应用 handler 返回,再提交游标和 ACK。handler 应以接收身份、设备、消息 ID 和业务语义建立幂等键;已读状态由应用在用户实际阅读后单独提交。History 用于浏览历史,不替代实时交付和 ACK。
|
|
57
|
+
|
|
58
|
+
### 3.1 消息类别
|
|
59
|
+
|
|
60
|
+
连接协商 `message_classes_v1` 后,消息按类别和 peer/群范围分别拉取、保存游标并恢复:
|
|
61
|
+
|
|
62
|
+
| 类别 | 用途 | 应用可见性 |
|
|
63
|
+
| --- | --- | --- |
|
|
64
|
+
| `normal` | 普通业务消息 | 交付到普通消息事件或 batch |
|
|
65
|
+
| `control` | 应用自行定义的控制消息 | 仍由应用接收、持久化和处理 |
|
|
66
|
+
| `sdk_control` | SDK 协议消息,例如 `aun.agent_md.changed` | 只交给 SDK 内部处理器,不进入普通消息事件、公开 History 正文或发送正文回包 |
|
|
67
|
+
|
|
68
|
+
应用发送自己的控制消息时使用加密的 `control` 类别。`sdk_control` 是 SDK 协议保留类别;应用业务 payload 不应冒充 SDK 协议。
|
|
69
|
+
|
|
70
|
+
```ts
|
|
71
|
+
await client.message.send({ to: peerAid, encrypt: true,
|
|
72
|
+
message_class: 'control',
|
|
73
|
+
payload: { type: 'app.control.v1', request_id: operationId } });
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
若远端尚未协商分类能力,分类控制拉取依赖服务端兼容路径。控制消息的应用业务状态仍由应用保存;SDK 持久化的是分类游标和交付/ACK 恢复责任。
|
|
77
|
+
|
|
78
|
+
SDK 内部 `sdk_control` 消息会校验解密后受保护头中的类别、协议和版本。内部消费或应用交付成功后才持久推进游标并 ACK;ACK 响应丢失时恢复原 ACK,证明过期时重新扫描续证。身份或连接换代后,旧异步结果不能提交到新会话。
|
|
79
|
+
|
|
80
|
+
### 3.2 Ownership 审批不是名片变更通知
|
|
81
|
+
|
|
82
|
+
Ownership 操作通过 `aun.ownership.sdk.v1` 控制协议。应用订阅 `ownership.request`,完成业务授权后调用接受或拒绝 API:
|
|
83
|
+
|
|
84
|
+
```ts
|
|
85
|
+
client.on('ownership.request', async value => {
|
|
86
|
+
const request = value as { operation_id: string; sub_aid: string };
|
|
87
|
+
if (!await authorizeOwnershipRequest(request)) return;
|
|
88
|
+
await client.acceptOwnershipRequest(request.operation_id);
|
|
89
|
+
const status = await client.checkOwnershipConsensus(request.sub_aid);
|
|
90
|
+
if (status.status === 'consensus') await enableSharing(status);
|
|
91
|
+
});
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
`acceptOwnershipRequest()` 返回的 `completed` 表示本次本地步骤完成,不单独证明 NS 已形成共识。共享或授权决策应以 `checkOwnershipConsensus()` 的结果为准。Owner 审批过程中写入的 `owner.md` 及其 Ownership 控制消息,不等于后文 `owned_agentmd.changed` 的 `agent.md` 上传通知。
|
|
95
|
+
|
|
96
|
+
## 4. 凭证与业务授权
|
|
97
|
+
|
|
98
|
+
SDK 提供结构化 `aun-cap/1`、语义/混合 `aun-cap/semantic-1`、消息证据、撤销状态和 Usage 的签验 API。应用负责提供可信证书和当前状态材料,并将认证通道取得的真实主体、目标、方法、参数、request ID、nonce 和业务事实绑定到验证上下文。
|
|
99
|
+
|
|
100
|
+
示例中的 `loadStructuredTrust`、`authContext`、`packageContext`、`requestParams` 等由应用实现或提供,不是 SDK 全局变量;证书、状态材料和请求参数应取自可信来源及本次真实业务请求。
|
|
101
|
+
|
|
102
|
+
结构化凭证沿用创建、登记回执验证、状态/撤销查询和完整 `verify()` 流程。TS 普通 `verify()` 为同步操作;需要网络的证书和状态取材应在调用前异步完成。`verifySignature()` 可做签名预检,不能替代包含能力、受众、当前状态及实际请求约束的完整验证。
|
|
103
|
+
|
|
104
|
+
```ts
|
|
105
|
+
const credential = client.credential.create(draft, signer);
|
|
106
|
+
const context = await loadStructuredTrust(credential);
|
|
107
|
+
const report = client.credential.verify(credential, {
|
|
108
|
+
...context, audience: businessServiceAid, subject: signer.aid,
|
|
109
|
+
ns: 'files', action: 'read', resource: '/reports', params: requestParams });
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
语义/混合凭证在原件之外还会使用确认元数据、来源链和服务登记。业务需先验证 request 和 credential package,再按 `online` 或 `bounded` 状态策略复核实际调用。消息正文证据和附件引用需与原始信封、接收身份及历史签署材料绑定。模型判断、成员/代表授权和最终额度事务属于应用责任;SDK 的 `checked`/`required` 结果不能替代应用的业务后置条件。
|
|
113
|
+
|
|
114
|
+
```ts
|
|
115
|
+
const packageValue = await client.credential.buildPackage(lineage);
|
|
116
|
+
const request = await client.credential.buildRequest(requestInput);
|
|
117
|
+
const requestReport = await client.credential.verifyRequest(request, authContext);
|
|
118
|
+
const packageReport = await client.credential.verifyPackage(request.grant, packageContext);
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
语义原件签署、确认、消息证据、撤销和 Usage 的字段合同见[凭证与组织服务应用集成专题](凭证与组织服务SDK应用集成指南.md)及[凭证与组织服务开发移植专题](凭证与组织服务SDK开发与移植指南.md)。
|
|
122
|
+
|
|
123
|
+
## 5. 组织成员与实体身份
|
|
124
|
+
|
|
125
|
+
组织和群使用各自的实体生命周期,不以普通 agent 的 Ownership 双文件流程代替实体 owner 确认。组织创建和转让使用 SDK 当前调用取得的确认结果、owner 和实体证书;续办应沿原 checkpoint 恢复,不从旧身份材料重造新操作。
|
|
126
|
+
|
|
127
|
+
```ts
|
|
128
|
+
const organization = await client.createOrg({ org_id: orgAid,
|
|
129
|
+
name: organizationName }, { aidStore: store });
|
|
130
|
+
const query = client.org.prepareRequest('org.member.get', {
|
|
131
|
+
org_id: orgAid, member_aid: signer.aid,
|
|
132
|
+
}, orgServiceAid, signer);
|
|
133
|
+
const member = await client.org.member.get(query);
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
申请、邀请、成员 CAP、代表调用、冻结/退出与 owner 转让仍须由应用验证实际 actor、成员关系、凭证能力和业务请求。Group/Org 名片的 owner 关系由对应服务权威确认,不能从 frontmatter 的 `owner` 字段单独推断共享关系。
|
|
137
|
+
|
|
138
|
+
## 6. Storage 与本地解析缓存
|
|
139
|
+
|
|
140
|
+
普通 Storage/Group FS 读取可使用 SDK 的读缓存;读取调用传 `noCache: true` 时绕过有效缓存并请求服务端校验,但返回结果仍可能更新缓存,这不是 no-store。Ownership 的 owner.md 共识读取使用权威 Storage 读取,由 SDK 核对 `head_object` 的摘要和 revision 后决定是否复用已验正文。
|
|
141
|
+
|
|
142
|
+
```ts
|
|
143
|
+
const object = await client.storage.lowlevel.getObject({ owner: signer.aid,
|
|
144
|
+
objectKey: objectKey, noCache: true });
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
`AIDStore.resolve(aid, { ownership })` 同时解析 peer 身份、名片和可选的 Ownership 快照。快照可在 agent.md 的 AID、ETag 和正文摘要匹配时复用;`forceRefresh` 本身不保证绕过 Ownership 快照。确需绕过该快照时,可使用已存在的 `ownershipTtlMs: 0` 选项。独立获取当前共识时,优先调用公开 `client.checkOwnershipConsensus(aid)`。
|
|
148
|
+
|
|
149
|
+
## 7. agent.md 上传、下载与 Ownership 共识
|
|
150
|
+
|
|
151
|
+
### 7.1 上传和读取规则
|
|
152
|
+
|
|
153
|
+
上传和下载使用不同 schema 入口。上传前除 schema 外,SDK 仍检查正文格式、AID、签名和证书;读路径允许普通 agent 名片缺少关系声明,并保留历史读取兼容。
|
|
154
|
+
|
|
155
|
+
| 名片类型 | 上传要求 | 下载要求 |
|
|
156
|
+
| --- | --- | --- |
|
|
157
|
+
| 普通非 human、非 group/org | 必须有 `owner` 和有效 Ownership 声明;适用的旧 proof 也须含完整必要签名材料 | 可以没有声明;出现关系材料时仍按对应格式与签名路径检查 |
|
|
158
|
+
| `human` | 禁止出现 `owner`、`ownership`、`ownership_proof` 或 `ownership_release` | 同样禁止这些字段,包括空值 |
|
|
159
|
+
| `group`/`org` | 通用上传 schema 仅要求 `owner` 字段存在;实际 owner 关系由实体服务确认 | 保留实体签名、证书指纹和历史兼容校验 |
|
|
160
|
+
|
|
161
|
+
普通 agent 的声明不单独证明共享共识。Group/Org 通过生命周期和对应服务确认实际 owner 关系;不要用普通 Ownership statement 为实体名片推导关系。
|
|
162
|
+
|
|
163
|
+
```ts
|
|
164
|
+
const signed = signer.signAgentMd(validFrontmatter).data.signed;
|
|
165
|
+
const uploaded = await store.uploadAgentMd(signer.aid, signed);
|
|
166
|
+
if (!uploaded.ok) throw new Error(uploaded.error.message);
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
SDK 和 NS 上传入口都按 `human`、普通非 human agent、`group`/`org` 分支。NS 的实体路径除 schema 外,还核验权威实体类型、当前 owner、实体证书和上传者授权;schema 分支只要求 `owner` 字段存在,不等于服务端只检查该字段。普通上传候选须满足上述声明要求;`human` 不能通过增加空字段绕过限制。Group/Org 使用实体生命周期提供的 owner 和证书上下文上传。
|
|
170
|
+
|
|
171
|
+
普通 agent 下载允许名片没有 Ownership 声明;下载成功只说明对应读取及名片校验通过,不代表 Ownership 关系已达成共识。声明存在时仍按对应格式与签名路径检查。
|
|
172
|
+
|
|
173
|
+
### 7.2 绑定和状态查询
|
|
174
|
+
|
|
175
|
+
普通 Ownership 2.1 以 `agent.md`、`owner.md` 和 NS 当前投影共同验收。`bindOwneraid()`/`bindSubaid()` 发起操作并返回当次任务结果;`acceptOwnershipRequest()` 执行已授权请求。`OwnershipTaskResult.status === 'completed'` 仅表示这次本地动作和通知步骤结束,最终关系仍要查看共识。
|
|
176
|
+
|
|
177
|
+
```ts
|
|
178
|
+
const task = await client.bindOwneraid(ownerAid);
|
|
179
|
+
const status = await client.checkOwnershipConsensus(signer.aid);
|
|
180
|
+
if (status.status === 'consensus') await enableSharing(status);
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
公开 `checkOwnershipConsensus()` 没有 `fresh` 参数。SDK 先完成普通查询的完整文件/签名/Storage 核验;首轮 `consensus` 直接返回,首轮任何非 `consensus` 状态会再调用既有 fresh 路径一次,NS 请求带 `Cache-Control: no-cache`,再按既有规则核验 NS 投影和 Ownership 文件,返回第二轮结果。pending 投影复核时,NS 会读取 `owner.md` 并尝试晋升;SDK 仍完整验证相关文件、签名和共识结果,不能将 pending 状态本身视为共识。第二轮仍非一致时原样返回,不递归、不轮询。应用无需通过重签名、重复绑定或重复审批来刷新状态;该请求头不表示 NS 服务缓存或 Storage 缓存都被强制绕过。
|
|
184
|
+
|
|
185
|
+
`checkOwnershipConsensus()` 覆盖 `consensus`、`released`、`unbound`、`single_sided`、`invalid`、`unavailable` 和 `not_applicable`。对于 `group`/`org`,`not_applicable` 表示应使用相应实体生命周期查询,而非普通 agent 的双文件共识。
|
|
186
|
+
|
|
187
|
+
## 8. Owner agent.md 上传变更事件
|
|
188
|
+
|
|
189
|
+
上传成功后,SDK 将对应的通知待办和名片提交状态一起持久保存,以固定 `message_id` 发送加密 `aun.agent_md.changed` v1 `sdk_control` 消息。发送前会重新确认当前归属;如果身份变化或关系已不匹配,不会把通知续发给旧 Owner。发送失败保留本次通知记录,不自动重试,也不影响已成功的上传结果。
|
|
190
|
+
|
|
191
|
+
Owner 收到内部控制消息后,SDK 将其作为取证触发信号:下载并验签名片、核对当前 owner 关系及 ETag,通过后再生成 `owned_agentmd.changed` 应用事件。应用事件包含被管理 AID、ETag 和事件 ID,不直接把原始控制封套暴露给应用。应用 handler 应完成自己的持久更新后再 resolve;若 handler 失败,SDK 保留该事件,后续仅在收到对应目标的通知时再次尝试交付。SDK 不通过连接、重连或定时任务恢复通知待办;该事件是 `agent.md` 更新通知,不是 owner.md 审批回执。
|
|
192
|
+
|
|
193
|
+
```ts
|
|
194
|
+
client.on('owned_agentmd.changed', async value => {
|
|
195
|
+
const event = value as { aid: string; etag: string; event_id: string };
|
|
196
|
+
await refreshApplicationIndex(event.aid, event.etag, event.event_id);
|
|
197
|
+
});
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
该流程仅由上传操作触发,处理本次提交对应的 AID;SDK 不扫描 AIDs 目录、Storage 的 `sub_aids/` 或群及组织清单,也不执行周期对账。应用仍须按 `event_id` 或 AID/ETag 幂等处理自身业务副作用。不要把 agent.md 更新通知与 Ownership 审批消息、owner.md 上传或共识状态合并为同一个业务事件。
|
|
201
|
+
|
|
202
|
+
## 9. 风控状态与重试
|
|
203
|
+
|
|
204
|
+
TypeScript SDK 仅在受验证的 WSS 连接、SSL 校验开启且服务端协商 `risk_test_v1` 与签名键时接入风控状态。SDK 验证 `ECDSA-P256-SHA256` 签名、issuer、AID、device、slot/connection 主体及 revision 后应用策略,并按身份和设备持久状态。连接级策略不作为新的连接状态自动沿用;旧 Ed25519 风控键不再接受,TS/JS 读取仅含旧键的本地风控记录会返回 `risk_state_unavailable`,不会自动迁移。
|
|
205
|
+
|
|
206
|
+
应用可以读取只读快照 `client.riskState`,也可监听 `risk_state_changed`。状态为 `restricted`、`blocked` 或 `recovered`;SDK 先应用并保存策略,再发送专用 `gateway.risk_ack` 并通知应用。原始风控封套不作为普通应用消息投递。
|
|
207
|
+
|
|
208
|
+
```ts
|
|
209
|
+
client.on('risk_state_changed', event => updateRiskView(event));
|
|
210
|
+
const currentRisk = client.riskState;
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
请求 scope 策略在 RPC/HTTP 实际发送前执行门控。普通 agent.md HTTP 与 Ownership HTTP 使用不同 scope;TS 检查 WSS 与 SSL 开关,不额外检查 Gateway 主机与 AID issuer 是否同域。HTTP 429 的 `retry_after_ms` 或 `Retry-After` 只对相同 origin 与 path 建立短期退避;SDK 不替应用重放业务写入。应用应识别首次请求的结果状态,按原业务幂等键安全重试。Gateway 4029 可推迟 SDK 重连。
|
|
214
|
+
|
|
215
|
+
SDK 的本地门控是协作响应,不能替代服务端限流、封禁和资源准入。配套服务端须提供协商能力、签名风控状态、ACK 接口和相应执行策略;服务能力缺失时,不应假定 SDK 单侧可以建立全局限制。
|
|
216
|
+
|
|
217
|
+
## 10. 升级与验收
|
|
218
|
+
|
|
219
|
+
将 TS 运行时和包配置核对到 0.5.28,并保留现有身份目录、seed、设备和 slot。浏览器应用同时核对所安装浏览器包版本。升级后先做类型检查和本地针对性回归,再按实际部署场景验收普通消息、应用 control、SDK control、Ownership 状态、Owner 通知恢复和风控服务协商;测试项存在不代表线上场景已通过。
|
|
220
|
+
|
|
221
|
+
| SDK | 应用接入差异 |
|
|
222
|
+
| --- | --- |
|
|
223
|
+
| TypeScript | Node 文件 store;语义与结构化 facade 按各自 API;`riskState` 提供只读快照 |
|
|
224
|
+
| JavaScript | `@agentunion/fastaun-browser`;IndexedDB/WebCrypto;`riskState` 提供只读快照 |
|
|
225
|
+
| Python | async RPC 和签验;公开 `get_risk_state()` |
|
|
226
|
+
| Go | `context`/`error`;`RiskState()` 快照 |
|
|
227
|
+
|
|
228
|
+
跨端字段和服务依赖见 [parity 0.5.28](../../python/CHANGES_FOR_PARITY.md#v0528--校验控制消息与风控未发布)。Ownership、控制消息和风控能力均须与服务端版本配套;本指南不声称 SDK 已发布、服务已部署或线上验收已通过。使用完毕调用 `await client.close()`;仍要复用同一 client 时可先 `await client.disconnect()` 后按应用生命周期重连。
|