@agentunion/fastaun 0.5.21 → 0.5.23

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 (75) hide show
  1. package/CHANGELOG.md +58 -1
  2. package/_packed_docs/CHANGELOG.md +58 -1
  3. package/_packed_docs/INDEX.md +469 -453
  4. package/_packed_docs/KITE_DOCS_GUIDE.md +169 -164
  5. 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
  6. 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
  7. package/_packed_docs/protocol/06-/346/234/215/345/212/241/345/215/217/350/256/256.md +5 -5
  8. package/_packed_docs/protocol/11-Storage-/345/255/220/345/215/217/350/256/256.md +30 -8
  9. package/_packed_docs/protocol/Ownership/345/215/217/350/256/256/345/256/232/344/271/2112.1.md +669 -666
  10. 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
  11. 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
  12. package/_packed_docs/sdk/06-API/346/211/213/345/206/214.md +16 -0
  13. package/_packed_docs/sdk/09-group-rpc-manual.md +10 -0
  14. package/_packed_docs/sdk/09-storage-rpc-manual.md +64 -7
  15. package/_packed_docs/sdk/09-/345/207/255/350/257/201/346/234/215/345/212/241RPC/346/211/213/345/206/214.md +3 -1
  16. package/_packed_docs/sdk/09-/347/273/204/347/273/207/346/234/215/345/212/241RPC/346/211/213/345/206/214.md +2 -0
  17. package/_packed_docs/sdk/AUN_DOCS_GUIDE.md +138 -134
  18. package/_packed_docs/sdk/INDEX.md +255 -239
  19. package/_packed_docs/sdk/Ownership-SDK/347/274/226/346/216/222/346/214/207/345/215/2272.1.md +939 -930
  20. 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 -363
  21. 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 -553
  22. 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 +4 -4
  23. package/_packed_docs/sdk/Ownership2.1/350/257/246/347/273/206/350/256/276/350/256/241.md +484 -480
  24. 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
  25. 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
  26. package/dist/agent-md.d.ts +16 -2
  27. package/dist/agent-md.js +59 -23
  28. package/dist/agent-md.js.map +1 -1
  29. package/dist/aid-store.d.ts +1 -0
  30. package/dist/aid-store.js +43 -8
  31. package/dist/aid-store.js.map +1 -1
  32. package/dist/auth.d.ts +7 -0
  33. package/dist/auth.js +222 -70
  34. package/dist/auth.js.map +1 -1
  35. package/dist/client/delivery.d.ts +28 -0
  36. package/dist/client/delivery.js +399 -44
  37. package/dist/client/delivery.js.map +1 -1
  38. package/dist/client/group-state.js +3 -0
  39. package/dist/client/group-state.js.map +1 -1
  40. package/dist/client/rpc-pipeline.js +28 -2
  41. package/dist/client/rpc-pipeline.js.map +1 -1
  42. package/dist/client/v2-e2ee.js +109 -39
  43. package/dist/client/v2-e2ee.js.map +1 -1
  44. package/dist/client.d.ts +3 -0
  45. package/dist/client.js +114 -26
  46. package/dist/client.js.map +1 -1
  47. package/dist/group-fs.d.ts +1 -0
  48. package/dist/group-fs.js +37 -19
  49. package/dist/group-fs.js.map +1 -1
  50. package/dist/org-protocol.d.ts +11 -0
  51. package/dist/org-protocol.js +154 -19
  52. package/dist/org-protocol.js.map +1 -1
  53. package/dist/ownership-v21.d.ts +21 -3
  54. package/dist/ownership-v21.js +135 -37
  55. package/dist/ownership-v21.js.map +1 -1
  56. package/dist/ownership-workflow.d.ts +7 -2
  57. package/dist/ownership-workflow.js +173 -17
  58. package/dist/ownership-workflow.js.map +1 -1
  59. package/dist/storage/lowlevel.d.ts +6 -0
  60. package/dist/storage/lowlevel.js +24 -7
  61. package/dist/storage/lowlevel.js.map +1 -1
  62. package/dist/storage/read-cache.d.ts +70 -0
  63. package/dist/storage/read-cache.js +625 -0
  64. package/dist/storage/read-cache.js.map +1 -0
  65. package/dist/storage/vfs.d.ts +2 -0
  66. package/dist/storage/vfs.js +50 -15
  67. package/dist/storage/vfs.js.map +1 -1
  68. package/dist/tools/cross-sdk-agent.d.ts +21 -1
  69. package/dist/tools/cross-sdk-agent.js +301 -19
  70. package/dist/tools/cross-sdk-agent.js.map +1 -1
  71. package/dist/transport.js +6 -2
  72. package/dist/transport.js.map +1 -1
  73. package/dist/version.d.ts +1 -1
  74. package/dist/version.js +1 -1
  75. package/package.json +1 -1
@@ -1,173 +1,266 @@
1
1
  # 凭证与组织服务 SDK 应用集成指南
2
2
 
3
- > 适用版本:四套 AUN SDK `0.5.19`,组织服务协议 `0.8`。
4
- >
5
- > 本文面向使用 SDK 的应用开发者。它描述当前代码已经提供的本地协议助手、facade 和服务端闭环;字段级冻结契约以 [组织服务 0.8 详细设计](../../../extensions/services/docs/org/0.8/17-凭证与组织服务详细设计.md) 为准。`14-App接入.md` 是产品界面设计,`11-RPC与SDK.md` 仍包含提出稿方法面,不能单独作为当前实现清单。
3
+ Org `0.8`,SDK `0.5.19` 基线及 `0.5.22` 工作区增量(未发布)。下文使用 Node TS;字段见 [Credential RPC](09-凭证服务RPC手册.md)/[Org RPC](09-组织服务RPC手册.md),内部实现见 [移植指南](凭证与组织服务SDK开发与移植指南.md)。
6
4
 
7
5
  ## 1. 先确认交付边界
8
6
 
9
- SDK 提供两类入口:
7
+ `client.credential` 处理凭证,`client.org` 处理组织/成员及请求准备。业务走 Gateway service-plane,Kernel 只做诊断;带 CID 的 credential.status 是业务查询。先确认服务已部署。
10
8
 
11
- | 入口 | 作用 | 当前可用方法 |
12
- |---|---|---|
13
- | `credential` | 创建、离线验签、完整验证、登记、吊销、状态和吊销列表 | `register`、`revoke`、`status`、`revocationList` |
14
- | `org` | 组织生命周期、成员、组织侧凭证状态、审计、授权检查和请求准备 | 以服务 manifest 与本指南第 5 节为准 |
15
-
16
- Credential 和 Org 是业务服务;`credential.register/revoke/status`(携带 `credential_cid` 时)/`credential.revocationList` 及组织业务 RPC 均经 Gateway service-plane 调用,Kernel 只承载控制面生命周期和 health/status 诊断,不承载凭证、成员或权限业务 RPC。四端 facade 存在不表示目标服务已经部署。探活应使用部署探针或受控的控制面诊断接口;不要把 `credential.status` 一概当作探活:携带 `credential_cid` 的 `credential.status` 是业务状态查询,走 service-plane。服务缺失、证书不可用、数据库不可用时,不能把本地 helper 成功当作服务端授权成功。
17
-
18
- 当前服务端明确保留但尚未实现的入口只有 `org.resource.create`、`org.task.create`、`org.host.add`、`org.workflow.create`;Python 和 Go 仍暴露对应子 facade 以保持统一入口,调用这四个方法时服务端返回业务码 `NOT_IMPLEMENTED`。其它 `org.resource.*`、`org.task.*`、`org.host.*`、`org.workflow.*` 方法不在当前 dispatcher 中,调用时按 JSON-RPC `Method not found` 处理。TS/JS 可通过 `client.call` 访问这些方法,结果遵循同一规则。
9
+ 保留的 org.resource.create/task.create/host.add/workflow.create 返回 NOT_IMPLEMENTED,其他未注册方法返回 Method not found。
19
10
 
20
11
  ## 2. 运行前准备
21
12
 
22
- 应用需要准备:
23
-
24
- 1. 一个已登录的 AUN `AUNClient` 和当前 AID。请求的认证主体来自当前会话,不能用 `from` 参数冒充另一个主体。
25
- 2. 颁发者或组织实体的本地私钥、证书和证书指纹。SDK 的 signer 至少提供 `aid`、`certPem`、`certFingerprint` 和 `sign`。
26
- 3. 一个按证书指纹返回受信 X.509 证书的 resolver。resolver 可返回 PEM、DER 字节,或严格标准 Base64 DER。
27
- 4. 完整验证所需的状态、成员关系和 Ownership resolver。验证失败、状态未知或 resolver 不可用都按拒绝处理。
28
- 5. 若创建或转让组织,使用 `AIDStore` 保存组织实体的私钥和证书。组织服务不保存组织私钥,转让也不能把旧私钥复制给新 owner。
29
-
30
- 连接认证、AIDStore 和 token 生命周期沿用现有 SDK 文档;本文只覆盖凭证和组织业务。
13
+ 准备已连接客户端、本人 signer 和可信证书/状态 resolver;状态未知不授权。ownerSigner/memberSigner 属于当前会话,orgSigner 是 owner 本地组织实体身份;创建/转让使用固定持久 AIDStore。服务 target 使用 credential.{issuer}/org.{issuer},已签材料固定原请求和成员。
31
14
 
32
15
  ## 3. 凭证的应用流程
33
16
 
34
17
  ### 3.1 创建并保留完整凭证
35
18
 
36
- 凭证是签名对象 `aun-cap/1`。应用只向 `credential.create` 传入未签名字段和颁发者 signer;SDK 会补 `cid`、签发时间、根凭证默认字段和签名。`credential.sub` 必须是真正持有并使用凭证的 AID,不能改成 owner、代理人或服务 AID。
19
+ ```mermaid
20
+ flowchart LR
21
+ A[issuer 创建并签署 CAP] --> B[登记完整凭证]
22
+ B --> C[验证服务登记回执]
23
+ C --> D[交付 holder]
24
+ D --> E[每次请求完整 Verify]
25
+ E -->|全部检查通过| F[执行业务]
26
+ ```
37
27
 
38
28
  ```ts
39
- const credential = await client.credential.create({
40
- sub: holderAid, aud: [serviceAid], exp, key_version: signer.certFingerprint,
41
- cap: [{ ns: 'files', action: 'read', resource: '/reports', constraints: [] }]
42
- }, signer);
29
+ const credential = client.credential.create({
30
+ sub: holderAid, aud: [serviceAid], exp, key_version: issuerSigner.certFingerprint,
31
+ cap: [{ ns: 'files', action: 'read', resource: '/reports', constraints: [] }],
32
+ }, issuerSigner);
43
33
  ```
44
34
 
45
- 成员角色凭证不要手工拼装。先创建或取得完整 `membership_binding`,再调用 `org.member.createCredential`(Python/Go 为 `create_credential`/`CreateCredential`);helper 会固定 `iss`、`sub`、`aud`、`role.*` 能力和 `ext` 成员绑定字段,并拒绝冲突覆盖。
35
+ sub 是实际 holder;保存完整签名对象。成员 CAP 用 org.member.createCredential(binding, orgSigner, options),不手工拼装角色字段。
46
36
 
47
37
  ### 3.2 选择正确的验证级别
48
38
 
49
- `verifySignature` 只验证凭证结构、签名、证书指纹和可选时间/受众。它适合展示或接收前的快速预检,不能得出“当前请求有权执行”的结论。
39
+ `verifySignature` 仅做结构、证书指纹和签名预检,可选时间/受众;执行授权使用完整 `verify`:
50
40
 
51
- 完整 `verify` 必须提供:
41
+ ```ts
42
+ const checked = client.credential.verify(credential, {
43
+ ...trustedResolvers, ...actualRequest,
44
+ audience: serviceAid, subject: holderAid, rootIssuer: issuerAid,
45
+ ns: 'files', action: 'read', resource: '/reports',
46
+ });
47
+ ```
52
48
 
53
- - `audience`、实际 `subject`、`ns/action/resource`;
54
- - 实际 `method/target/params/request_id/nonce/request_binding`;
55
- - `resolveCertificate`;
56
- - 根/父凭证状态 resolver。存在 `parent` 时,父链必须使用受信强 `resolveStatusProof` resolver 返回的完整状态 proof,不能把原始 RPC 响应或字符串 `active` 当作父链证明。resolver 必须预先验证 Credential 服务签名、服务证书信任链和当前撤销状态,并确认 proof 对应实际查询的 `request_id`、nonce 和 target;SDK 再检查 proof 字段、CID/hash、状态及证明时间窗;
57
- - 成员凭证的当前 `membershipBinding` 和 `resolveMembershipStatus`;
58
- - 代表调用的 `actor`、`for`、`representationProof`、当前 Ownership resolver 和 actor 状态 resolver。
49
+ actualRequest 含真实 method/target/params/requestId/nonce/requestBinding。trustedResolvers 提供可信证书和当前状态;父链强 resolveStatusProof 须先验服务签名/信任/撤销及原查询,再由 SDK 核对 CID、全文 hash 和时间窗,不能返回裸 active。
59
50
 
60
- 完整验证依次检查签名、时间、audience、父链收窄、当前状态、能力约束、请求绑定、成员 binding 和代表关系。返回的 `signature_valid=true` 不覆盖任何后续检查;`CREDENTIAL_STATUS_UNKNOWN`、`CREDENTIAL_REQUEST_BINDING_INVALID`、`MEMBERSHIP_STATE_INVALID` 和 `ROLE_ACCESS_DENIED` 均应停止副作用操作。
51
+ 成员另传当前 membershipBinding/resolveMembershipStatus;代表调用另传 actor/for/representationProof 及当前 Ownership/actor 状态。任一步失败即停。
61
52
 
62
53
  ### 3.3 登记、回执和吊销
63
54
 
64
- Credential Service 只接受完整已签名凭证,不提供公开 `credential.prepare`。登记流程是:
55
+ registrationParams 为持久保存的完整请求:原 request_id/nonce、registrar_aid、credential、request_binding;转交另含 issuer 登记授权。SDK 无 credential.prepare,按 [RPC 手册](09-凭证服务RPC手册.md#credentialregister) 准备。
56
+
57
+ ```ts
58
+ import { isJsonObject } from '@agentunion/fastaun';
59
+ const registered = await client.credential.register(registrationParams);
60
+ if (!isJsonObject(registered)) throw new Error('登记响应无效');
61
+ client.credential.verifyRegistrationReceipt(
62
+ registered.registrationReceipt, credential, registrationParams,
63
+ resolveCertificate, credentialServiceAid,
64
+ );
65
+ ```
65
66
 
66
- 1. 颁发者直接调用 `credential.register`,或签署 `registration_authorization` 让指定服务转交。
67
- 2. 检查返回的 `registrationReceipt`:服务签名、`service_aid`、`registrar_aid=credential.iss`、CID、完整凭证摘要、原 `request_id`/nonce、状态和有效期必须全部匹配。
68
- 3. Org 入组最终化前再次验证回执。登记成功不等于成员已经 `active`。
69
- 4. 失败补偿使用原 CID、原操作上下文和明确吊销授权调用 `credential.revoke`;`NOT_FOUND` 或未知状态不能当作补偿完成。
67
+ 回执须匹配服务/issuer、CID/全文 hash、原请求、状态和有效期;Org 验回执并最终化后成员才 active。
70
68
 
71
- `credential.register`、`credential.revoke`、携带 `credential_cid` 的 `credential.status` 及 `credential.revocationList` 请求都必须携带 `request_id`、nonce 和 `request_binding`,绑定真实 method、target、参数摘要和时间窗。`credential.revocationList` 没有单一凭证目标,其 `request_binding.credential_cid` 固定为空字符串;`params_hash` 仍覆盖 `issuer_aid`、`cursor`、`limit`、`since_event_seq` 等全部业务参数。除该列表方法外,凡要求 `request_binding` 的 Credential 业务请求都必须绑定非空凭证 CID。状态 proof 有独立 `asOf/proofExpiresAt` 窗口;父链状态 proof 还必须包含 `credential_hash`、`request_id`、nonce、target、responder 和签名。状态未知时应用不得放行写操作。`revocationList` 用于增量补齐吊销事件,断序或证明过期时暂停受影响凭证的副作用操作。
69
+ ```ts
70
+ const result = await client.credential.revoke(revocationParams);
71
+ ```
72
+
73
+ revocationParams 含原 CID、吊销授权/原因及本次绑定。仅明确 revoked 算完成;NOT_FOUND/unknown 不算。原 method/request ID/摘要幂等恢复,不能换 ID。所有 Credential 请求绑定方法、服务、参数、请求及时间窗;仅 revocationList 的 CID 为空。
72
74
 
73
75
  ## 4. 组织成员流程
74
76
 
75
77
  ### 4.1 组织创建
76
78
 
77
- 创建组织需要两个身份:当前会话 owner signer,以及本地生成并保存的组织实体 signer。创建入口按 SDK 分别为 Python `client.org.lifecycle.create`、TypeScript/JavaScript `client.createOrg`、Go `client.CreateOrg`;TypeScript/JavaScript 的生命周期 facade 在提供 `aidStore` 时会转入高层创建流程,否则直接调用 `org.lifecycle.create`。按创建流程提供完整 binding、CAP 和授权材料,并完成实体主签、当前 owner token 上传的组织名片发布;低层请求应先用各端的 `org.prepareRequest`/`org.prepare_request` 准备,再调用对应 facade。
79
+ ```mermaid
80
+ flowchart LR
81
+ A[owner 会话和持久 AIDStore] --> B[生成并保存组织实体身份]
82
+ B --> C[准备 owner binding、CAP 和登记授权]
83
+ C --> D[Org 登记 CAP、验回执并创建组织]
84
+ D --> E[实体主签,owner token 上传名片]
85
+ ```
86
+
87
+ ```ts
88
+ const created = await ownerClient.createOrg(
89
+ { org_id: orgAid, name: '协作组织' }, { aidStore: ownerStore },
90
+ );
91
+ ```
78
92
 
79
- 组织名片使用 `aid=org_id`、`type=org`、当前 `owner` 和实体证书指纹。实体私钥生成主签并显式 signer_aid=org_id,当前 owner 以本人 token 上传,无需实体登录;可选一个或多个当前 owner 附签,存在就必须全块验证,取消实体额外 V2 上传授权。现代实体指纹严格匹配,Org 不开放旧实体上传;通用 Ownership facade 对组织实体返回 not_applicable。文件签验与 HTTP 多签协商见 [Ownership 应用指南](Ownership2.1-SDK应用集成指南.md#34-通用签验与多签名片) 及 [API 手册](06-API手册.md#通用-sign--verify)。
93
+ 组织名片实体主签、owner token 上传,含当前 owner/实体指纹,附签存在则全验。组织不走通用 Ownership 绑定,名片待办与创建结果分开。
80
94
 
81
95
  ### 4.2 申请加入与邀请
82
96
 
83
- 申请模式:
97
+ ```mermaid
98
+ sequenceDiagram
99
+ participant M as 成员 App
100
+ participant O as owner/管理员 App
101
+ participant G as Org 服务
102
+ participant C as Credential 服务
103
+ alt 成员申请
104
+ M->>G: join:成员签 binding
105
+ G-->>O: 待审批
106
+ O->>G: approveJoin:同条款组织签名、CAP、登记授权
107
+ else 组织邀请
108
+ O->>G: invite:每个目标独立 binding/CAP/登记授权
109
+ G-->>M: 原邀请材料
110
+ M->>G: inviteAccept:保留原材料,补目标成员签名
111
+ end
112
+ G->>C: 登记成员 CAP
113
+ C-->>G: 签名回执
114
+ G->>G: 验回执并最终化成员
115
+ G-->>M: active 与完整成员包
116
+ ```
117
+
118
+ 成员申请:
119
+
120
+ ```ts
121
+ const joinParams = memberClient.org.prepareRequest('org.member.join', {
122
+ org_id: orgAid, member_type: 'human', requested_role: 'member', terms,
123
+ }, orgServiceAid, memberSigner);
124
+ const application = await memberClient.org.member.join(joinParams);
125
+ ```
126
+
127
+ 审批端的 applicationBinding/terms 取原申请响应 application 内的 membership_binding/terms;ownerCredentials 为审批者当前 binding/CAP:
84
128
 
85
- 1. 成员创建 `membership_binding`,由成员 signer 签 `member_signature`。
86
- 2. owner/admin 对同一不可变条款签 `org_signature`,并准备完整成员 CAP 和登记授权。
87
- 3. 调用 `org.member.approveJoin`;服务登记 CAP、验证回执,然后完成成员关系。
129
+ ```ts
130
+ const binding = ownerClient.org.member.signBinding(applicationBinding, orgSigner, 'org');
131
+ const approval = ownerClient.org.prepareRequest('org.member.approveJoin', {
132
+ org_id: orgAid, terms, membership_binding: binding, credentials: ownerCredentials,
133
+ }, orgServiceAid, ownerSigner, { orgSigner });
134
+ await ownerClient.org.member.approveJoin(approval);
135
+ ```
88
136
 
89
- 邀请模式:
137
+ 邀请端复用原 invitation 的组织、binding、terms、CAP 模板和登记授权:
90
138
 
91
- 1. 组织 signer 为每个目标 AID 创建独立 binding、nonce、request ID 和 `org_signature`。
92
- 2. 目标成员签 `member_signature` 后调用 `org.member.inviteAccept`。
93
- 3. 服务完成登记和最终化。每个目标的 binding、CAP 和授权包不得互换。
139
+ ```ts
140
+ const accepted = memberClient.org.prepareRequest(
141
+ 'org.member.inviteAccept', invitation, orgServiceAid, memberSigner,
142
+ );
143
+ await memberClient.org.member.inviteAccept(accepted);
144
+ ```
94
145
 
95
- `org.member.join`/`inviteAccept` 的首次入组均使用以 `membership_id`、原 `request_id` 和 nonce 绑定的专用 admission request binding,不带 `credential_cid`,也不要求已有 active 成员 CAP。本人直接调用和代表调用都必须由目标成员私钥提供 `member_signature`;仅当 `for != signer.aid` 代表另一个目标时,才由认证 actor signer 签 admission representation proof,并通过当前 ownership/status 校验。本人直接 `inviteAccept` 复用邀请保存的组织签名、CAP 模板和登记授权,SDK 不重签或重造这些材料。owner 的代表证明不能替代目标成员签名,也不能把 `credential.sub` 改成 owner。
146
+ 首次入组绑定 membership_id 和原 request ID/nonce,不带 CID/已有 CAP。本人和代表均须目标成员签名;for≠signer.aid 另验代表证明和当前 Ownership/actor 状态。
96
147
 
97
148
  ### 4.3 查询、状态变更与续期
98
149
 
99
- 成员状态优先于角色和能力:`banned`/`ended` 拒绝授权,`frozen` 拒绝普通写操作但允许离职收尾,`offboarding` 只允许收尾动作。应用显示成员状态应使用 `org.member.get` 返回的签名 `membership_status`,不要仅凭历史 binding 或 CAP 状态判断当前成员资格。
150
+ ```mermaid
151
+ flowchart LR
152
+ A[同一成员关系,准备新 binding/CAP/登记授权] --> B[renewCredential:旧 CID+当前版本 CAS]
153
+ B --> C[登记新 CAP 并验回执]
154
+ C -->|成功| D[提交新成员版本,再撤旧 CAP]
155
+ C -->|失败| E[仅补偿撤新 CAP]
156
+ D --> F[立即保存完整新成员包]
157
+ ```
158
+
159
+ renewalMaterial 含旧 CID、expected_version、双签新 binding、terms、新 CAP/登记授权及当前调用授权:
100
160
 
101
- 成员离职/移除的正常顺序是 `leave` 或 `kick` → `offboard(confirm)` → 持久化 `ended` → 吊销本组织明确拥有撤销权限的成员 CAP → 删除 active projection。失败时保留后台续跑记录。
161
+ ```ts
162
+ const renewal = memberClient.org.prepareRequest(
163
+ 'org.member.renewCredential', renewalMaterial, orgServiceAid, memberSigner,
164
+ );
165
+ await memberClient.org.member.renewCredential(renewal);
166
+ const current = await memberClient.credential.current(memberCredential);
167
+ ```
168
+
169
+ 续期保持原成员关系,响应后立即持久完整成员包,credential.current 无需等事件。长期凭证 READY 后及在线每60秒扫描,显式短期凭证不自动续期。
102
170
 
103
- 原关系内换发使用 `org.member.renewCredential`:提交旧 CID、当前版本、完整新 binding、组织签名 CAP 和登记授权;新 CAP 登记并确认后才撤旧 CAP,失败只撤新 CAP。不要把 renew 当成重新加入,也不要给旧 CAP 全局豁免。 四 SDK 的本地托管长期凭证自动检查由连接进入 READY 触发,并在在线期间每 60 秒重新扫描;断线、关闭及身份变化取消调度,异步扫描不得用旧身份提交。自动续期状态机已完成四 SDK 定向实现与验证,不据此冻结跨版本消息契约;需要明确控制续期时机的应用仍使用上述显式接口,接口不变。 已批准的受限跨期恢复只处理本地原期限内已持久化且已发送的同一操作,固定原 CID/request_id/nonce、双签、登记授权及版本 CAS;严格新鲜签名 Credential status 和当前成员确认同一新 CAP/完整摘要/版本已生效后,仅保存已有结果。无原回执的 generic 恢复须以新鲜签名 Credential status 及 registrationConfirmedAt 证明同一 CAP/完整摘要已提交,仅保存 issuer 本地 checkpoint,不导入 holder 账户、不发送 issued 结果消息、不重新 register;远端 holder 仍须原有效 registrationReceipt 完成交付。未提交、unknown、revoked 或不匹配均拒绝,不重登记、不重签。历史回执仅供私有受限恢复验真,公开回执接口及 CAP 当前有效期不放宽;四 SDK 已完成定向实现与验证;具体定向与真实验收范围见 [审查报告 §7.14](../../../extensions/services/docs/org/0.8/凭证与组织服务及四SDK审查报告.md),不代表全环境验收。
171
+ 当前资格看签名 membership_status:banned/ended 拒绝,frozen 禁普通写,offboarding 仅收尾。离职按 leave/kick→offboard→ended→撤有权吊销的 CAP→清 active projection,失败续跑。
104
172
 
105
173
  ## 5. 组织请求与跨设备代表
106
174
 
107
175
  ### 5.1 统一请求准备
108
176
 
109
- 需要业务授权或 request binding 的请求应调用 `prepareRequest`/`prepare_request`/`PrepareRequest`,不论它是读还是写。`org.member.list`、`org.member.get`、`org.credential.getStatus` 属于受保护业务读取,必须提供当前成员 binding 和对应 CAP,并准备 AAD、`request_binding` 与 `client_signature`。公开组织的 `org.lifecycle.list/get` 按可见性规则处理;`org.health/status` 是控制面诊断路径。首次 `org.member.join` 和 `org.member.inviteAccept` 无论本人还是代表调用,都使用 membership binding 中的 `request_id`/nonce 和 `membership_id` 专用 admission `request_binding`,不带 `credential_cid`;本人调用不需要 admission representation proof,也不要求已有 active 成员 CAP,`inviteAccept` 复用邀请保存的组织签名、CAP 模板和登记授权。只有代表目标节点(`for != signer.aid`)才生成 admission representation proof,并通过当前 ownership/status 校验。准备函数负责:
177
+ ```mermaid
178
+ flowchart LR
179
+ A[业务参数+本次授权包] --> B[prepareRequest:原 ID/nonce、AAD、request binding]
180
+ B --> C[必要时补代表证明]
181
+ C --> D[RPC 管线生成外层 client_signature]
182
+ D --> E[Gateway service-plane]
183
+ E --> F[服务独立重算签名、摘要和当前权限]
184
+ ```
110
185
 
111
- - 自动生成或复用 `request_id`、nonce;锚定入组流程时必须与 binding 一致;
112
- - 为所有 `org.*` 请求加入 `aad.org_id` 并拒绝不匹配的已有 AAD;仅 `org.lifecycle.list` 及 health/status 路径允许 `org_id:null`,`org.member.list` 仍必须绑定具体 `org_id`;
113
- - 生成 `request_binding`,其 `params_hash` 覆盖真实业务参数、AAD 和授权包,排除 `request_binding`、`client_signature`、`_` 前缀字段,并排除 `credentials.representation_proof` 避免循环;
114
- - 在需要时生成 membership binding、member CAP、registration authorization 和 representation proof;已有签名或 binding 冲突直接拒绝,不重写原材料。
186
+ 受保护读取也须准备请求,例如查询自己的成员状态:
115
187
 
116
- 随后把返回 params 原样交给 `client.call` 或对应 facade。客户端 RPC 管线会为 `org.*` 自动生成 `client_signature`;应用不要把该字段提前复制到另一个请求,也不要改写已准备的摘要。
188
+ ```ts
189
+ const params = memberClient.org.prepareRequest('org.member.get', {
190
+ org_id: orgAid, member_aid: memberSigner.aid, credentials: memberCredentials,
191
+ }, orgServiceAid, memberSigner);
192
+ const member = await memberClient.org.member.get(params);
193
+ ```
194
+
195
+ 准备后原样发送,RPC 管线补 client_signature。受保护读取也需当前 binding/CAP;公开 lifecycle.get/list 按可见性处理。AAD 绑定 org_id,仅 lifecycle.list/health/status 可为 null。
117
196
 
118
197
  ### 5.2 代表操作
119
198
 
120
- `for` 是业务目标,不是认证身份。当前会话 actor 代表另一个 AID 时,SDK 必须绑定:`from`、`for`、`represented`、实际服务 target、method、params_hash、nonce 和时间窗;使用已有 CAP 的代表请求绑定 credential CID,首次入组 admission 请求绑定 `membership_id`。服务端还要通过受信 Ownership 和 actor 状态 resolver 确认 actor 当前有权代表目标;封禁、状态未知或 resolver 缺失均拒绝。
199
+ 参数增加 for: holderAid,授权包仍属 holder。prepareRequest 绑定双方、方法、服务、摘要和时间窗;首次 admission 绑定 membership_id,其他代表绑定 CID。owner 不能替代目标成员签名。
121
200
 
122
201
  ### 5.3 服务事件
123
202
 
124
- Credential/Org 事件先独立验证 responder、目标 AID、时间窗、服务证书和签名,再进入 SDK 去重/handler。去重键包含 responder、event_id 和当前 AID;事件过期、证书不可信或未知凭证事件不能触发本地授权更新。
203
+ SDK 验服务、接收 AID、证书、签名和时间窗后去重;撤销同步如下:
204
+
205
+ ```mermaid
206
+ flowchart LR
207
+ A[撤销推送/已签列表页] --> B[验签及身份/连接代次复核]
208
+ B --> C[按 authority、CID 保留最大 event_seq]
209
+ C --> D[持久保存快照]
210
+ D --> E[后续授权检查使用]
211
+ ```
212
+
213
+ 单条推送不推进分页,旧页不覆盖新证据,本地缺 CID 不证明有效。连接后一小时首次兜底拉列表,之后每小时;重连重新计时,与60秒凭证扫描独立。
125
214
 
126
215
  ## 6. 所有权转让与实体材料
127
216
 
128
- 转让不是一次普通 RPC:
217
+ ```mermaid
218
+ sequenceDiagram
219
+ participant O as 原 owner
220
+ participant N as 目标 owner SDK
221
+ participant G as Org 服务
222
+ participant CA as CA
223
+ O->>G: transfer:当前授权请求
224
+ G-->>N: transfer proposal
225
+ N->>N: 签接受材料,持久保存新 P-256 私钥与 checkpoint
226
+ N->>G: transferAccept stage=rekey
227
+ G->>CA: 复核代际并提交新公钥
228
+ CA-->>G: 新实体证书
229
+ G-->>N: pending_finalization 与新证书
230
+ N->>N: 导入证书,重签新旧 owner binding/CAP
231
+ N->>G: stage=finalize,独立持久 request ID
232
+ G->>G: 新 owner 生效,旧 owner 降 member,撤旧 CAP
233
+ N->>N: 新实体主签,owner token 上传名片
234
+ ```
129
235
 
130
- 1. 目标 owner 在本地持久生成新的 P-256 私钥。
131
- 2. `transferAccept(stage=rekey)` 提交新 SPKI 公钥和旧 owner 降级预检材料。
132
- 3. 服务返回新证书和 `pending_finalization`;目标 owner 导入新证书。
133
- 4. 用新实体 signer 重签双方 binding/CAP,准备新的登记授权,以独立请求标识调用 `stage=finalize`。
134
- 5. 成功后原 owner 降为 member,旧 CAP 持久吊销;新 owner 重新上传实体名片。
236
+ 原 owner 准备并调用 org.lifecycle.transfer;目标验证 proposal,用 signTransferAcceptance 签接受字段。transferParams 保留这些字段、原 transfer_id、双方完整成员材料及授权包:
135
237
 
136
- 四端高层流程会把输入摘要、proposal、阶段 params 和私钥 checkpoint 保存到本地。恢复时 transfer ID、owner、输入摘要、公钥和阶段上下文必须一致;材料变化返回 conflict,不发新 RPC。服务断线不应重新生成另一把 key 或重复创建另一份 proposal。
238
+ ```ts
239
+ const transferred = await targetClient.completeOrgTransfer(
240
+ transferParams, { aidStore: targetStore },
241
+ );
242
+ ```
243
+
244
+ 恢复沿用原 transfer ID、输入、阶段参数和私钥;缺 key 报 persistence_unavailable,材料变化报 conflict,TS/JS 精确完成态可重放。详见 [移植 §6](凭证与组织服务SDK开发与移植指南.md#6-高层实体身份和转让编排)。
137
245
 
138
- 解散高层入口以当前 signer 和调用方提供的当前成员 binding/CAP 准备业务授权请求,补齐 request ID、nonce、AAD 和 `request_binding`,核验已有请求绑定并保留原成员材料。仅在服务确认 `dissolved` 后,四端记录当前实体证书指纹失效并清理创建/转让 checkpoint、待上传名片和当前设备/slot 恢复状态;保留磁盘私钥,已加载的 AID/signer 不追溯失效,后续 `AIDStore.load` 拒绝该证书。创建或转让后的名片待办保存完整多签原文、原 CAS、固定 owner 与实体证书指纹,由应用显式重试,重连不自动 PUT。重试核对当前生命周期与证书代际,原条件完整且同代际全文/ETag 已证明提交时只观察完成;转移、rekey 或解散后停止旧待办,不换身份、字节或条件重签。专属 create/transfer 自身 checkpoint 恢复机制不变。取消额外 V2 授权及其过期窗口,组织成员 binding/CAP 签名规则不变。
246
+ 解散用 client.dissolveOrg(params, { aidStore }),提供当前 binding/CAP;确认 dissolved 后才失效本地证书并清恢复状态,保留磁盘私钥。名片失败稿保留完整多签、固定 owner/代际和原 CAS,仅显式重试,重连不 PUT;代际变化停止旧待办。
139
247
 
140
248
  ## 7. 四端入口速查
141
249
 
142
- | 能力 | Python | TypeScript | JavaScript | Go |
143
- |---|---|---|---|---|
144
- | 凭证 facade | `client.credential` | `client.credential` | `client.credential` | `client.Credential()` |
145
- | 组织 facade | `client.org` | `client.org` | `client.org` | `client.Org()` |
146
- | 请求准备 | `org.prepare_request` | `org.prepareRequest` | `org.prepareRequest` | `org.PrepareRequest` |
147
- | binding | `create_binding/sign_binding` | `createBinding/signBinding` | `createBinding/signBinding` | `CreateBinding/SignBinding` |
148
- | 成员 CAP | `create_credential` | `createCredential` | `createCredential` | `CreateCredential` |
149
- | 完整验证 | `credential.verify` | `credential.verify` | `credential.verify` | `Credential().Verify` |
150
- | 转让签名 | `sign_transfer_acceptance` | `signTransferAcceptance` | `signTransferAcceptance` | `SignTransferAcceptance` |
250
+ | 能力 | Python | TS/JS | Go |
251
+ | --- | --- | --- | --- |
252
+ | 业务入口 | client.credential/org | client.credential/org | client.Credential()/Org() |
253
+ | 请求准备 | org.prepare_request | org.prepareRequest | Org().PrepareRequest |
254
+ | 组织创建/转让 | org.lifecycle.create/transfer_accept | createOrg/completeOrgTransfer | CreateOrg/CompleteOrgTransfer |
151
255
 
152
- Python RPC helper 是 async;浏览器 JS 的密码学 helper 返回 Promise;Node.js TypeScript helper 同步;Go 返回 `(value, error)`。协议字段和错误码必须保持一致,不能把语言异步差异写入 wire 格式。
256
+ Node TS 协议 helper 同步,浏览器密码 helper 为 Promise;Python RPC async/协议 helper 同步,Go 返回 value/error。文件 AIDStore.sign/verify 的 TS/JS 均须 await。
153
257
 
154
258
  ## 8. 错误与重试
155
259
 
156
- - 只重试读请求,或同一 `request_id`、同一 method、同一摘要的幂等重试。
157
- - `CREDENTIAL_IDEMPOTENCY_KEY_REUSE`、签名错误、权限拒绝、binding 冲突和成员状态拒绝不重试。
158
- - `CREDENTIAL_STATUS_UNKNOWN`、服务不可用、数据库不可用可在状态窗口内重试,但重试前重新确认 resolver 和证书;不要降级为 allow。
159
- - 记录 CID、receipt_id、membership_id、request_id 和摘要即可;不把私钥、token 或完整凭证写入普通日志。
160
- - RPC 成败看结构化 error/exit code,不解析展示文本。
260
+ 仅重试读取或原 method/request ID/摘要不变的幂等操作。签名/权限/binding/状态/幂等冲突不盲重试;未知暂缓副作用,创建补偿遇幂等冲突停自动补偿。
161
261
 
162
- ## 9. 验收清单
262
+ 跨期恢复只确认原期限内已持久且已发送的既成结果,不重登记/重签。无原回执时只保存 issuer 结果,holder 交付仍需原有效回执,边界见 [移植 §4.2](凭证与组织服务SDK开发与移植指南.md#42-登记授权和回执)。
163
263
 
164
- 应用上线前至少验证:
165
-
166
- - 离线签名预检与完整 Verify 的分界;父链强 status proof;成员状态和代表状态未知均拒绝;
167
- - 登记回执的服务签名、CID/hash、registrar、request_id/nonce 和有效期;失败补偿能得到明确 revoked 结果;
168
- - join 和 invite 的双方签名、每目标独立 binding、首次 admission 的 target signature;
169
- - client signature、AAD、request binding 的摘要重算与跨语言向量一致;
170
- - transfer rekey/finalize 断线恢复、私钥 checkpoint、旧 owner 降级和名片重新上传;
171
- - 服务未部署、服务证书无效、Credential 状态未知、组织数据库不可用时均 fail-closed。
264
+ ## 9. 验收清单
172
265
 
173
- 相关协议、共同向量和服务验收见 [组织服务 0.8 详细设计](../../../extensions/services/docs/org/0.8/17-凭证与组织服务详细设计.md)、[TDD 实施计划](../../../extensions/services/docs/org/0.8/18-凭证与组织服务TDD实施计划.md) 和 [四 SDK 对齐变更清单](../../python/CHANGES_FOR_PARITY.md)。
266
+ 覆盖完整 Verify、回执、双签入组、受保护读取、撤销乱序/重启、续期完整包、转让两阶段丢响应。运行见 [测试指南](../aun测试运行指南.md),版本边界见 [四端对齐清单](../../python/CHANGES_FOR_PARITY.md)。