@agentunion/fastaun 0.5.21 → 0.5.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/CHANGELOG.md +58 -1
  2. package/_packed_docs/CHANGELOG.md +58 -1
  3. package/_packed_docs/INDEX.md +465 -453
  4. package/_packed_docs/KITE_DOCS_GUIDE.md +168 -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 +1 -1
  27. package/dist/agent-md.js +11 -4
  28. package/dist/agent-md.js.map +1 -1
  29. package/dist/auth.d.ts +1 -0
  30. package/dist/auth.js +18 -2
  31. package/dist/auth.js.map +1 -1
  32. package/dist/client/delivery.d.ts +28 -0
  33. package/dist/client/delivery.js +399 -44
  34. package/dist/client/delivery.js.map +1 -1
  35. package/dist/client/group-state.js +3 -0
  36. package/dist/client/group-state.js.map +1 -1
  37. package/dist/client/rpc-pipeline.js +28 -2
  38. package/dist/client/rpc-pipeline.js.map +1 -1
  39. package/dist/client/v2-e2ee.js +109 -39
  40. package/dist/client/v2-e2ee.js.map +1 -1
  41. package/dist/client.js +38 -10
  42. package/dist/client.js.map +1 -1
  43. package/dist/group-fs.d.ts +1 -0
  44. package/dist/group-fs.js +37 -19
  45. package/dist/group-fs.js.map +1 -1
  46. package/dist/org-protocol.d.ts +1 -0
  47. package/dist/org-protocol.js +54 -7
  48. package/dist/org-protocol.js.map +1 -1
  49. package/dist/ownership-v21.d.ts +21 -3
  50. package/dist/ownership-v21.js +135 -37
  51. package/dist/ownership-v21.js.map +1 -1
  52. package/dist/ownership-workflow.d.ts +7 -2
  53. package/dist/ownership-workflow.js +173 -17
  54. package/dist/ownership-workflow.js.map +1 -1
  55. package/dist/storage/lowlevel.d.ts +6 -0
  56. package/dist/storage/lowlevel.js +24 -7
  57. package/dist/storage/lowlevel.js.map +1 -1
  58. package/dist/storage/read-cache.d.ts +70 -0
  59. package/dist/storage/read-cache.js +625 -0
  60. package/dist/storage/read-cache.js.map +1 -0
  61. package/dist/storage/vfs.d.ts +2 -0
  62. package/dist/storage/vfs.js +50 -15
  63. package/dist/storage/vfs.js.map +1 -1
  64. package/dist/tools/cross-sdk-agent.d.ts +21 -1
  65. package/dist/tools/cross-sdk-agent.js +301 -19
  66. package/dist/tools/cross-sdk-agent.js.map +1 -1
  67. package/dist/transport.js +6 -2
  68. package/dist/transport.js.map +1 -1
  69. package/dist/version.d.ts +1 -1
  70. package/dist/version.js +1 -1
  71. package/package.json +1 -1
@@ -0,0 +1,212 @@
1
+ # AUN SDK 0.5.22 应用集成指南
2
+
3
+ 面向应用开发者,基于 0.5.21。本文对应 2026-10-23 的未发布源码,示例使用 TypeScript。消息持久化、batch 交付与 peer 同步沿用 [0.5.21 应用集成指南](0.5.21-SDK应用集成指南.md);SDK 实现见 [0.5.22 移植指南](0.5.22-SDK开发与移植指南.md)。
4
+
5
+ ## 1. 本版应用需要关注的变化
6
+
7
+ | 领域 | 应用需要处理的变化 |
8
+ | --- | --- |
9
+ | 消息/群 | 后台失败退避,群终态停止补拉;非 active 群跳过自动恢复和提案确认,权限以当前查询为准 |
10
+ | Ownership | 接入两种绑定顺序、用户审批和任务恢复,以 fresh 共识确认当前关系 |
11
+ | Credential/Org | SDK 合并撤销推送并每小时补拉;应用使用当前完整成员包,保留原任务、请求和候选密钥 |
12
+ | 文件读取 | 元数据和符合条件的 inline 正文默认缓存 60 秒;需立即观察变化时强制刷新 |
13
+
14
+ ## 2. 身份、存储与连接
15
+
16
+ Node.js `>=22.16.0` 使用 `@agentunion/fastaun`,浏览器使用 `@agentunion/fastaun-browser`。升级保留原 `aunPath`、解密配置、设备/slot、任务及续期 checkpoint;应用消息仍存业务数据库。
17
+
18
+ 加载已注册身份,`AUN_PATH`、`AUN_SEED` 由部署提供:
19
+
20
+ ```typescript
21
+ import { AIDStore, AUNClient } from '@agentunion/fastaun';
22
+ const store = new AIDStore({
23
+ aunPath: process.env.AUN_PATH!, encryptionSeed: process.env.AUN_SEED ?? '',
24
+ slotId: 'main', verifySsl: true,
25
+ });
26
+ const loaded = store.load('helper.agentid.pub');
27
+ if (!loaded.ok) throw new Error(loaded.error.message);
28
+ if (!loaded.data.aid.isPrivateKeyValid()) throw new Error('本身份私钥不可用');
29
+ const client = new AUNClient(loaded.data.aid);
30
+ ```
31
+
32
+ `AUNClient` 接收 AID 对象,连接配置传给 `connect()`。可信根与 TLS 见 [连接与认证](04-连接与认证.md)。首次注册用 `store.register()`;owner 可省略,携带时仅保存待审批意图,不表示绑定完成,不重复申请。
33
+
34
+ 浏览器 `store.load()` 需 `await`,身份与缓存使用 IndexedDB,`aunPath` 为本地命名空间;示例见 [浏览器差异](0.5.21-SDK应用集成指南.md#23-浏览器差异)。
35
+
36
+ ## 3. 消息订阅与同步状态
37
+
38
+ 连接前注册处理器:`saveIncomingMessage` 完成约定的持久处理后返回;`showOwnershipRequest` 展示审批后返回,不等待用户点击。
39
+
40
+ ```typescript
41
+ import type { EventHandler } from '@agentunion/fastaun';
42
+ declare const saveIncomingMessage: EventHandler;
43
+ declare const showOwnershipRequest: EventHandler;
44
+ client.on('message.received', saveIncomingMessage);
45
+ client.on('ownership.request', showOwnershipRequest);
46
+ await client.connect({ auto_reconnect: true });
47
+ ```
48
+
49
+ 已有 `message.batch`/`message.recalled` 处理器时复用;不注册丢弃消息的空回调。仅订阅 `ownership.*` 不启动 P2P 后台收取。READY 后补订阅也会恢复积压,仍受 `background_sync`、背压、退避及连接代际约束。Ownership 控制消息由 SDK 内部验签、持久消费。
50
+
51
+ `connect()` 返回不表示同步和业务恢复完成。分别显示连接、同步与任务状态;保持原有提交后 ACK 和业务已读契约。
52
+
53
+ 非成员、封禁、群不存在或已解散等终态错误会停止该群消息和事件同步,保留本地消息;用户手动拉取成功或连接换代后恢复,无需应用高频轮询。
54
+
55
+ ## 4. Ownership 2.1 审批与恢复
56
+
57
+ ### 4.1 公有入口
58
+
59
+ | 角色或动作 | TypeScript 方法 |
60
+ | --- | --- |
61
+ | sub 向 owner 申请绑定 | `client.bindOwneraid(ownerAid)` |
62
+ | owner 邀请 sub 绑定 | `client.bindSubaid(subAid)` |
63
+ | 本端用户明确同意/拒绝 | `client.acceptOwnershipRequest(operationId)`/`client.rejectOwnershipRequest(operationId, reason)` |
64
+ | 当前 owner 释放 sub | `client.releaseSubaid(subAid)` |
65
+ | 当前 owner 发起三方转移 | `client.transferSubaid(subAid, newOwnerAid)` |
66
+ | 检查当前关系 | `client.checkOwnershipConsensus(subAid)` |
67
+
68
+ sub-first 申请:
69
+
70
+ ```typescript
71
+ const task = await client.bindOwneraid('owner.agentid.pub');
72
+ console.log(task.operation_id, task.status);
73
+ ```
74
+
75
+ 保存 `operation_id`,订阅 `ownership.action_required/progress/completed/rejected/stopped/error`。`ownership.request` 展示已验证请求,有权用户明确决定后才调用同意/拒绝。事件载荷无 `event.data` 包装;字段见 [Ownership 应用指南](Ownership2.1-SDK应用集成指南.md#3-ec-cli-集成示例sub-发起human-owner-同意)。
76
+
77
+ ### 4.2 两种绑定顺序
78
+
79
+ | 发起方 | SDK 编排 | 应用应观察的结果 |
80
+ | --- | --- | --- |
81
+ | sub-first | fresh 确认无锁及 Stage 能力 → 暂存 sub 的 `agent.md` → owner 同意并发布本轮 `owner.md` → NS fresh 验收 | 暂存为 `single_sided`,不授权;验收时 sub 可离线,无须再次上传 |
82
+ | owner-first | fresh 确认无锁 → owner 条件发布 `owner.md` 并发请求 → sub 验签、同意后直接条件提交 `agent.md` | 不用 Stage,无 bind.accept/owner.ready 往返;以 fresh 共识确认成立 |
83
+
84
+ 服务端须支持 2.1 fresh 检查和条件发布;sub-first 还须通过 Stage 能力预检,`Protocol: 2.1` 不能替代该检查。
85
+
86
+ 拒绝清理由 SDK 按原件和 CAS 条件执行:sub-first 清理本轮未锁定候选;owner-first 的 sub 不上传名片,owner 条件删除匹配的未锁邀请。应用不手动删文件或替换提交条件。
87
+
88
+ `ownership.completed` 表示任务目标曾核验完成;展示当前关系仍须查询,不能凭 pending、ACK 或用户同意授权:
89
+
90
+ ```typescript
91
+ const relation = await client.checkOwnershipConsensus('helper.agentid.pub');
92
+ console.log(relation.status, relation.owner_aid);
93
+ ```
94
+
95
+ 仅 `consensus` 且参与方匹配时确认绑定。`single_sided/released/unbound/invalid/unavailable` 分别为准备中、已释放、未绑定、材料无效、暂不可确认;Group/Org 使用专属生命周期,返回 `not_applicable`。
96
+
97
+ ### 4.3 重连、冲突与 reset
98
+
99
+ 恢复原任务及其审批、签名字节、请求参数、摘要和提交条件。共识冲突时 SDK 额外 fresh 重查一次;仍不一致返回可重试 `unavailable`,应用保留现场。
100
+
101
+ 本地 revision 冲突、NS HTTP 412、Storage `-32009` 是三类 CAS 冲突;按当前事实恢复,不能换新 ETag/对象版本重试旧原件。`persistence_unavailable` 须先恢复原存储。
102
+
103
+ `resetOwnershipTask()` 仅归档本端发起的未完成任务,不解绑、不解锁、不删远端文件。须用户明确要求,新申请重新审批;启动、断网或写入结果不明时不 reset。详见 [CAS 恢复边界](Ownership2.1-SDK开发与移植指南.md#103-cas-冲突分类与恢复边界)。
104
+
105
+ ## 5. resolve:frontmatter 与 owner 展示
106
+
107
+ `AIDStore.resolve()` 返回完整原文 `agent_md.content` 和保留 YAML 嵌套类型的 `agent_md.frontmatter`;扩展字段使用前按应用约定收窄类型。
108
+
109
+ ```typescript
110
+ const profile = await store.resolve('alice.agentid.pub', { ownership: client });
111
+ if (!profile.ok) throw new Error(profile.error.message);
112
+ console.log(profile.data.agent_md?.frontmatter);
113
+ console.log(profile.data.ownership?.status, profile.data.ownership?.cached);
114
+ ```
115
+
116
+ | opts | 默认值 | 用途 |
117
+ | --- | --- | --- |
118
+ | `ownership` | 不传 | 传已有 client,复用共识检查 |
119
+ | `ownershipTtlMs` | 60,000 ms | 关系展示快照 TTL;`0` 每次查询 |
120
+ | `forceRefresh` | `false` | 刷新身份/名片及已请求的关系快照 |
121
+ | `skipAgentMd` | `false` | 省略名片输出;共识仍可内部读取权威材料 |
122
+ | `timeout` | 10,000 ms | 名片下载超时;共识沿用 client 配置 |
123
+
124
+ 成功 `data` 含 `aid`、可选 `agent_md/ownership` 和 `source`。ownership 可含 `owner_md` 原文、摘要及观测信息,随展示快照保存,不另存本地 owner.md。额外共识不可用时,外层仍可成功,关系为 `unavailable`。
125
+
126
+ 展示快照独立于文件缓存,不能用于授权。自有身份可能返回未发布草稿,须核对 `source`;名片更新保留关系字段、本人签名和原 CAS。完整契约见 [resolve 输入与输出](06-API手册.md#resolve-输入与输出)。
127
+
128
+ ## 6. Storage / Group FS 默认读缓存
129
+
130
+ ### 6.1 缓存策略
131
+
132
+ | 响应或调用条件 | 行为 |
133
+ | --- | --- |
134
+ | 缺少 `read_cache`,或为 `null` | 元数据默认 60 秒;实际 ≤65,536 字节且 SHA-256 校验通过的完整正文默认缓存 |
135
+ | 显式 `reusable: true` | 正文另须 `inline: true`;省略 `max_age_ms` 默认 60 秒,有限正数最多 60 秒 |
136
+ | 显式禁止或无效策略 | `reusable: false`、空策略、显式 null/非正数/非法 TTL 不复用 |
137
+ | 单次 `noCache: true` | 强制回源校验,可条件复用正文;结果仍按策略更新缓存,不是 no-store |
138
+ | `consistency: 'authoritative'` | 支持该参数的底层 RPC 完全旁路读缓存并读取权威事实 |
139
+
140
+ `read_cache` 是服务端响应策略,特定文件由服务端显式禁用缓存;应用用刷新选项控制单次调用。热命中和重启不续期,远端更新/撤权可能到刷新或 TTL 到期才被观察。
141
+
142
+ ### 6.2 普通读取与强制刷新
143
+
144
+ ```typescript
145
+ const path = 'owner.agentid.pub:/sub_aids/helper.agentid.pub/owner.md';
146
+ const bytes = await client.storage.readBytes(path);
147
+ const refreshed = await client.storage.readBytes(path, { noCache: true });
148
+ const stat = await client.storage.stat(path, { noCache: true });
149
+ ```
150
+
151
+ 普通 `owner.md` 读取默认缓存;Ownership 管理和 fresh 共识由关系门面读取权威原件。
152
+
153
+ 刷新可发送 `if_sha256`;`not_modified` 仅复用摘要匹配的已验证完整正文,无正文不能返回空文件。详细校验见 [Storage 缓存](09-storage-rpc-manual.md#sdk-默认读缓存)。
154
+
155
+ ### 6.3 Group FS 与使用边界
156
+
157
+ Group FS 使用同一策略,TS/JS 支持 `noCache: true` 并兼容 `no_cache`;类型化 Storage VFS 使用 `noCache`。刷新选项由 SDK 消费,不传为服务端业务字段;入口见 [Group FS](09-group-rpc-manual.md#sdk-默认读缓存)。
158
+
159
+ 范围读取、显式预签及大正文保留原下载路径。`storage.list_share_links/check_access/list_tokens` 始终回源且不使其它缓存失效;写删、移动、相关权限变更会失效。缓存按身份、网关与业务参数隔离。
160
+
161
+ 有限次授权的 inline 读取仅返回正文时计次;本地命中、HEAD、无正文 `not_modified` 不计次。大对象按下载授权计次。联网仍检查撤销、过期、身份及权限。
162
+
163
+ Node.js/Python/Go 使用 SQLite 索引与摘要正文,浏览器用 IndexedDB;默认内存/持久正文预算为 32/256 MiB。缓存会淘汰,不能替代身份、任务和应用数据库的持久存储。
164
+
165
+ ## 7. 凭证与组织服务
166
+
167
+ ### 7.1 撤销推送与小时补拉
168
+
169
+ SDK 验证并持久合并 `credential.revoked`、`credential.revocationList`,防止乱序覆盖和分页回退。连接一小时后首次补拉,此后每小时一次,重连重新计时;凭证续期仍每分钟检查。
170
+
171
+ 撤销快照存于 keystore/tokenstore 的 `credential_revocations_v1` metadata(浏览器为 IndexedDB),不是 JSONL 事件流水。缺少 CID 不表示有效,仍须完整凭证及父证明链验证;PKI CRL/OCSP 是另一套缓存。
172
+
173
+ ### 7.2 使用当前完整成员包
174
+
175
+ ```typescript
176
+ declare const originalCredentialCid: string;
177
+ const current = await client.credential.current(originalCredentialCid);
178
+ if (!current) throw new Error('没有当前托管凭证');
179
+ const credential = current.credential;
180
+ const membershipBinding = current.membership_binding;
181
+ ```
182
+
183
+ `credential.current()` 沿本地续期链查询当前记录。续期响应立即保存 credential、membership binding、terms、registrationReceipt、服务端版本及权威信息,不等成员事件。业务请求通过 request binding helper 使用当前完整包,不长期复用最初的 CAP。
184
+
185
+ `long_term=false` 不自动续期;续期仅更新当前成员账户。
186
+
187
+ ### 7.3 组织创建、转让及服务部署
188
+
189
+ | 场景 | 应用处理 |
190
+ | --- | --- |
191
+ | 创建补偿冲突 | `CREDENTIAL_IDEMPOTENCY_KEY_REUSE` 保留任务和原请求,核对冲突,不换 ID 自动重试 |
192
+ | Python 候选私钥丢失 | `persistence_unavailable`:恢复原私钥,不生成替代密钥继续原请求 |
193
+ | Go 证书指纹不匹配 | 保留原身份和材料,核对 CA 返回的实体证书指纹 |
194
+ | TS/JS 转让已完成 | 同 transfer ID、owner、原参数可重放结果;重连跳过 completed |
195
+ | 跨域实体名片重试 | TS/JS/Go 使用上传者所属域 token,访问实体所在域;保留原 CAS |
196
+
197
+ 配套服务须部署撤销幂等恢复、创建补偿冲突保护、换钥代际/DER 修复、成员包与定向通知原子保存,见 [服务部署要求](0.5.22-SDK开发与移植指南.md#55-配套-credential--org-服务修复)。应用以验证结果和当前查询恢复状态,不依赖通知及时到达。
198
+
199
+ 业务参数与审批见 [凭证与组织应用指南](凭证与组织服务SDK应用集成指南.md)。
200
+
201
+ ## 8. 升级与应用验收
202
+
203
+ | 顺序 | 验收内容 |
204
+ | --- | --- |
205
+ | 构建与部署 | SDK 产物、Gateway peer、NS 2.1/Stage、Storage 条件发布及 Credential/Org 服务版本匹配 |
206
+ | 持久恢复 | 原身份、设备/slot、任务、续期 checkpoint 和业务数据库可恢复 |
207
+ | 消息 | 连接前/后订阅、断线、背压、提交后 ACK、群终态停止与手动恢复 |
208
+ | Ownership | 两种顺序、缺 Stage、拒绝清理、sub 离线、原件变化及响应丢失;pending 不授权,reset 不解锁 |
209
+ | 缓存 | 缺省/显式策略、64 KiB 边界、刷新与条件复用、失效、重启不续期;普通/权威 owner.md 分别验证 |
210
+ | 凭证组织 | 小时补拉、完整续期包、短期不续期、原密钥恢复、完成重放及补偿冲突 |
211
+
212
+ 测试入口见 [移植验收](0.5.22-SDK开发与移植指南.md#8-移植与验收顺序),实际验证范围见 [parity](../../python/CHANGES_FOR_PARITY.md#v0522--相对于-v0521-发布基线的变更未发布)。关闭前完成应用持久处理,再调用 `client.close()`。
@@ -0,0 +1,199 @@
1
+ # AUN SDK 0.5.22 开发与移植指南
2
+
3
+ 面向 SDK 维护者及其它语言实现者,基于 [0.5.21 移植指南](0.5.21-SDK开发与移植指南.md)。本文对应 2026-10-23 的未发布源码;应用接线见 [应用集成指南](0.5.22-SDK应用集成指南.md),Rust 定位见第 7 节。
4
+
5
+ ## 1. 范围与参考
6
+
7
+ 对齐后台同步、群状态、Ownership 2.1、撤销同步、组织恢复和默认读缓存。沿用原 peer 同步、batch、提交后 ACK、签验和 checkpoint 契约;各端实现与验证记录见 [parity v0.5.22](../../python/CHANGES_FOR_PARITY.md#v0522--相对于-v0521-发布基线的变更未发布)。
8
+
9
+ ## 2. 后台同步退避与群终止
10
+
11
+ ### 2.1 按 namespace 退避
12
+
13
+ P2P、群消息、群事件、peer 目录和按 peer 恢复分别保存失败次数/重试时间,采用有上限的指数退避;已有等效机制可保留时长配置。
14
+
15
+ - Push/hint、分页和补拉合并需求,不覆盖未到期的退避。
16
+ - 等待时释放 Pull Gate,允许其它 namespace 和前台继续;前台保持原返回契约。
17
+ - 成功清除本 namespace 失败状态;身份、设备、slot 或连接换代时清旧状态并丢弃旧结果。
18
+
19
+ ### 2.2 群错误分类与停止
20
+
21
+ 优先使用布尔 `error.data.retryable`,缺失时按错误码/文本兼容判断:
22
+
23
+ | 错误类型 | 处理方式 |
24
+ | --- | --- |
25
+ | 临时网络或服务错误 | 按 namespace 退避重试 |
26
+ | 非成员、封禁、群不存在或已解散等终态 | 停止该群消息及事件 namespace,清理补拉、分页和 tail 待办 |
27
+
28
+ 群别名共用停止状态,Push/hint 和扫描不重启;手动拉取成功、身份或连接换代后恢复。保留本地消息/游标,失败页不确认。字段见 [Message](09-message-rpc-manual.md)/[Group RPC](09-group-rpc-manual.md)。
29
+
30
+ ## 3. 群身份恢复与提案确认
31
+
32
+ ### 3.1 自动任务检查群状态
33
+
34
+ 在自动恢复身份、绑定和确认提案的入口,跳过明确非 `active` 的群(包括 `suspended`),保留身份、消息及游标;缺少 `status` 时沿用兼容行为。
35
+
36
+ ### 3.2 确认提案前复查角色
37
+
38
+ 收到 `state_proposed` 或直接确认已有提案时,重查当前角色,仅 owner/admin 继续。按群串行,对成功 proposal 去重,保留身份、连接代次、proposal base 和 state hash 校验。
39
+
40
+ ## 4. Ownership 共识
41
+
42
+ ### 4.1 以 NS fresh 检查为权威
43
+
44
+ 关系版本和 `lock` 以 NS fresh 响应为准:保留 `X-AUN-Ownership-Check: 1`、禁用缓存及 multi-v1 协商。验证 `agent.md`、Storage `owner.md` 和关系声明,保留原文/摘要、存在性、ETag、30 秒观察窗口及 CAS 检查。
45
+
46
+ ### 4.2 冲突时立即重查一次
47
+
48
+ NS 元数据与已验签名片不一致,或 lock 与 owner.md 的 release/缺失状态冲突时,额外 fresh 重查并重验材料;两类冲突共用一次额度。
49
+
50
+ | 重查结果 | 处理方式 |
51
+ | --- | --- |
52
+ | NS 与文件状态一致,材料稳定 | 按新鲜 NS 状态继续 |
53
+ | 仍有冲突、材料变化或权威服务不可用 | 返回可重试的 `unavailable`,保留任务和文件 |
54
+ | 签名或关系材料无效 | 返回 `invalid` |
55
+
56
+ 流程末尾仍作稳定性复读。NS 仍 locked 而 owner.md 已 release/缺失时返回 `unavailable`;清理、重绑先确认解锁。配套 NS 须在权威 owner.md 缺失或 release 验签且复核稳定时返回 fresh `unlocked`,读取/验签失败返回错误。
57
+
58
+ ### 4.3 消息拉取与内部处理
59
+
60
+ P2P 后台拉取要求普通消息订阅(`message.received/recalled/batch`),仅 `ownership.*` 不足。连接前注册或 READY 后补注册均可恢复积压,仍遵守 `background_sync=false`、背压、退避和身份/连接代际。
61
+
62
+ Ownership 走正常 P2P 路径,由 SDK 解密、验签、持久消费;不为它绕过积压、另存普通消息待投递记录或改变提交/ACK 时序。接线见 [应用指南](Ownership2.1-SDK应用集成指南.md#32-两端分别装载自己的身份)。
63
+
64
+ ### 4.4 按发起方发布绑定原件
65
+
66
+ 两种绑定发起前均须 fresh 确认无锁,`invalid/unavailable` 不能视为无锁;已有锁只能由当前 owner 释放或转移。legacy 任务沿用原恢复路径。
67
+
68
+ | 阶段 | 移植要求 |
69
+ | --- | --- |
70
+ | sub 准备 | 持久化本轮审批、目标 owner/版本、完整签名 `agent.md` 及原 If-Match/If-None-Match 后再 PUT |
71
+ | Stage 预检 | 带 Check 的 fresh GET/HEAD 须返回 `X-AUN-Ownership-Stage: 1`;缺失即停止,`Protocol: 2.1` 不能替代 |
72
+ | Stage 提交 | `PUT /agent.md` 带 Stage 头;核对响应同一能力头、`X-AUN-Ownership-Status: pending`、`Lock: unlocked` 及候选版本 |
73
+ | pending 映射 | 公共共识为 `single_sided`、`owner_aid=null`,不新增公共状态,不按 released 或有效 owner 授权 |
74
+ | owner 同意 | 固定 pending 原文/摘要/ETag,再签发匹配本轮的 owner declare;旧 owner/版本文件不能代替审批 |
75
+ | 验收 | owner 等检查方触发 NS fresh,核验两份原件后清 pending、建立锁并同步副本;sub 可离线,无须再次 PUT/重签 |
76
+ | sub-first 拒绝 | 仅条件清理本轮原文/摘要/ETag 匹配且仍 pending/unlocked 的候选;预存清理签字节和原 CAS,丢响应复用,候选变化或已验收即停止 |
77
+ | owner-first | 持久化签名 owner.md/原 Storage 条件 → 条件发布确认 → 发 `bind.request`;sub fresh 验证、明确同意后持久化 agent.md/原 NS 条件,直接 PUT;不用 Stage,无 bind.accept/owner.ready 往返,NS fresh 验收 |
78
+ | owner-first 拒绝 | sub 不上传;owner fresh 确认无锁及原件匹配,以最后读取并核对的当前 `version` 作 `expected_version` 删除邀请;版本冲突停止 |
79
+
80
+ checkpoint 区分起始原件与候选,不能仅凭 owner/数字版本复用审批。reset 仅归档本端发起的未完成任务,不删远端候选、不解锁;新申请重新审批,真实 released 关系先清旧字段。本地 revision、NS 412、Storage `-32009` 分别按 [CAS 恢复边界](Ownership2.1-SDK开发与移植指南.md#103-cas-冲突分类与恢复边界) 处理,不换条件重试旧原件。
81
+
82
+ NS 的 `ownership_pending` 与名片 CAS 一起持久化;pending 名片是当前权威原件,Storage 副本在 fresh 验收后同步。协议见 [读取、并发与接口](../protocol/Ownership协议定义2.1.md#33-读取并发与接口)。
83
+
84
+ ## 5. 凭证撤销与成员续期
85
+
86
+ ### 5.1 验证并合并推送
87
+
88
+ 将 `credential.revoked`、`credential.revocationList` 合并到持久撤销快照:
89
+
90
+ - 验证服务签名、authority、接收身份、有效时间和撤销材料。
91
+ - 按 authority/CID 保留最大 `event_seq`,推送与分页并发合并,不覆盖新记录。
92
+ - 异步验证/持久化前后核对身份和连接代次,丢弃旧结果;用于完整凭证和父证明链验证。
93
+
94
+ 四端使用 tokenstore/keystore 的 `credential_revocations_v1` metadata(浏览器 IndexedDB),按 authority 保存 CID 序号、分页 checkpoint 和证明时间窗。它不是 JSONL 流水,缺少 CID 不证明有效;结构见 [撤销快照](凭证与组织服务SDK开发与移植指南.md#54-撤销同步与持久快照0522)。
95
+
96
+ ### 5.2 保持分页连续
97
+
98
+ 单条推送只更新 CID,保留 `since_event_seq`/cursor。已验证列表页覆盖当前 checkpoint 时才前推,迟到页不回退。
99
+
100
+ ### 5.3 每小时补拉
101
+
102
+ 连接一小时后首次补拉,此后每小时执行;重连重新计时,断线/身份变化取消旧调度。与 Ownership、长期凭证续期等每分钟任务分开调度。
103
+
104
+ ### 5.4 同步保存成员续期结果
105
+
106
+ 续期成功立即保存凭证、绑定、条款、登记回执、服务端版本及权威信息,供 `credential.current` 读取完整成员包,不等待事件。仅更新当前成员账户;`long_term=false` 跳过后台及写前自动续期。保留加密存储、CAS、历史和防回滚检查。
107
+
108
+ ### 5.5 配套 Credential / Org 服务修复
109
+
110
+ 部署依赖:
111
+
112
+ - `credential.revoke` 按原 request ID/参数摘要恢复持久结果,校验 CID 和 revoked 状态;冲突/损坏不能返回成功。
113
+ - 创建补偿遇 `CREDENTIAL_IDEMPOTENCY_KEY_REUSE` 持久保存冲突并停止,不换 request ID 重试。
114
+ - 转让换钥前复核证书/公钥代际,新公钥用规范 DER Base64;已有 checkpoint 恢复原请求。
115
+ - 原子保存新旧 owner 成员包与定向 `org.member.changed` 通知;失败通知保留待办并按组织轮转。SDK 仍验完整包,续期保存不依赖通知。
116
+
117
+ 详见 [Credential RPC](09-凭证服务RPC手册.md#credentialrevoke)、[Org RPC](09-组织服务RPC手册.md#组织生命周期)及 [服务实现要求](凭证与组织服务SDK开发与移植指南.md#7-服务端兼容实现要点)。
118
+
119
+ ## 6. 默认读缓存、语言专项修复与版本
120
+
121
+ ### 6.1 Storage / Group FS 默认读缓存
122
+
123
+ 同时接入读取入口、后端和失效机制,元数据/正文分别判定:
124
+
125
+ | 条件 | 移植要求 |
126
+ | --- | --- |
127
+ | 无 `read_cache`,或为 `null` | 元数据默认 60 秒;完整正文实际 ≤65,536 字节且 SHA-256 校验通过时默认缓存 |
128
+ | 显式策略 | 须 `reusable: true`,正文另须 `inline: true`;省略 `max_age_ms` 默认 60 秒,有限正数最多 60 秒;显式禁止、空对象、null/非正数/非法 TTL 不复用 |
129
+ | 单次刷新 | TS/JS `noCache: true`、Python `no_cache=True`、Go Options `NoCache: true` 强制回源;TS/JS 底层 RPC/Group FS 兼容 `no_cache`,选项不传为业务字段 |
130
+ | 条件读取 | 过期/刷新可带 `if_sha256`;`not_modified` 须与已有已验证完整正文摘要匹配,无正文不能返回空文件。校验不受后续缓存许可影响;结果仍可缓存,刷新不是 no-store |
131
+ | 权威/特殊读取 | 支持 `consistency: "authoritative"` 的底层 RPC、范围及显式预签读取旁路缓存 |
132
+ | `owner.md` | 普通读默认缓存;Ownership 管理/fresh 共识读权威原件。resolve 展示快照独立维护,不能授权 |
133
+
134
+ 有限次授权的 inline 读取仅返回正文时计次;本地命中、HEAD、无正文 `not_modified` 不计次,额度耗尽仍可匹配 SHA 条件验证。大对象按 URL 签发/授权 302 计次,同 URL 有效期内为一次授权,不统计 OSS GET;联网仍核验撤销、过期、身份及权限。服务端 TTL 扣除元数据年龄和解析耗时,累计新鲜度不超过 60 秒及对象/授权有效期。
135
+
136
+ #### 持久层与容量
137
+
138
+ 索引与正文分离,不迁入业务数据、tokenstore 或 Ownership 任务:
139
+
140
+ | SDK | 缓存后端 |
141
+ | --- | --- |
142
+ | TypeScript / Python / Go | `{aunPath}/.cache/storage/index.sqlite3`(WAL):`cache_entries` 存元数据/验证/过期时间,`cache_blobs` 存摘要/大小/访问时间;正文为 `blobs/{sha256前2位}/{sha256}` |
143
+ | 浏览器 JavaScript | `aun-keystore` IndexedDB 的 `storage_cache_index`/`storage_cache_blobs` |
144
+
145
+ 默认预算:内存/持久正文 32/256 MiB、元数据 16 MiB,索引 999/9,999 条;正文按最近访问淘汰,索引按容量/时间淘汰。热命中、重启不续期,重启核验摘要。后端故障、正文丢失/损坏时降级内存或联网,不解释为远端不存在。
146
+
147
+ #### 隔离、失效与新鲜度
148
+
149
+ - 键含实际身份、网关、RPC 方法和规范化参数,隔离范围/token/share/ACL;排除刷新选项、条件摘要和重签材料。
150
+ - 合并同键冷读;写删、移动、ACL/token/share 和相关群权限变更使缓存失效。失效或身份/连接换代前的旧结果不得填回。
151
+ - 仅存可复用元数据及已验证正文,正文记录去掉下载 URL、临时票据、认证 token 和签名;下载时重新申请票据。
152
+ - 热命中不联网,远端变化到刷新/TTL 到期才被观察;管理/授权仍用权威入口。
153
+
154
+ 仅缓存读取白名单;四端 `storage.list_share_links/check_access/list_tokens` 始终回源且不使其它缓存失效。响应契约见 [Storage 手册](09-storage-rpc-manual.md#sdk-默认读缓存),跨端验证见 [parity 块⑦](../../python/CHANGES_FOR_PARITY.md#块⑦-storage--group-fs-默认读缓存)。
155
+
156
+ ### 6.2 语言专项修复与版本
157
+
158
+ | 适用端 | 需要完成的修改 |
159
+ | --- | --- |
160
+ | Python 共享身份目录 | 非 owner 跳过群恢复保留有效证书;owner 清除误失效标记前核对名片 owner、原证书指纹及现有私钥 |
161
+ | Python 名片 HEAD | Gateway 404 后回源 NS,再判缺失 |
162
+ | Go 存储错误 | `MapStorageError` 穿透 AUNError/包装错误,保留 Code/Data、not-found、retry_safe |
163
+ | Python 组织转让 | 原候选私钥丢失时保留 checkpoint,返回 `persistence_unavailable`,不生成替代密钥 |
164
+ | Go 组织转让 | 导入前核对证书指纹与 CA 的 `entity_cert_fingerprint` |
165
+ | TS/JS 组织转让 | 保存 completed,同 owner/转让 ID/原参数可重放;重连跳过已完成任务 |
166
+ | TS/JS 证书缓存 | `cleanExpiredCaches` 遵循 `chainCacheTtl`(默认 86,400 秒);JS PKI CRL/OCSP 用秒比较,与 Credential 小时补拉分离 |
167
+ | TS 当前实体证书 | 验证本次 PKI current 响应及新鲜元数据,不另按指纹取响应替代 |
168
+ | Python 文件展示 | CLI `fs cat` 无 Content-Type 且 ≤64 KiB 时尝试 UTF-8,失败回退二进制 |
169
+
170
+ 发布同步包、运行时、测试/项目配置及 V2 envelope 的版本为 `0.5.22`,保留历史文档版本。
171
+
172
+ ## 7. Rust 移植清单
173
+
174
+ 路径以 `acp-app/aun-so/rust/` 为根;复用现有分页退避、Pull Gate、群在途控制和验签。缓存按 §6.1 实现,其它定位如下:
175
+
176
+ | 项目 | 需要完成的修改 | 代码定位 |
177
+ | --- | --- | --- |
178
+ | 群错误/hint | 按 §2 保留 retryable、退避及群终态联动 | `crates/aun-auth/src/short_rpc.rs`:service_rpc_error;`crates/aun-client/src/actor.rs`:cleanup_failed_rpc、Tail demand |
179
+ | 群状态/提案 | 按 §3 检查状态、角色并去重 | `crates/aun-client/src/actor.rs`:群恢复、handle_group_v2_state_proposed |
180
+ | Ownership | 按 §4 接入 fresh、Stage、原件/CAS、pending 及两种绑定恢复 | `crates/aun-sdk/src/ownership_v21_workflow.rs` |
181
+ | 撤销推送 | 按 §5.1–5.2 验签、合并快照和分页 | `crates/aun-sdk/src/client.rs`:spawn_router;`credential_org.rs`:sync_revocations/快照 |
182
+ | 小时补拉 | 按 §5.3 独立调度 | `crates/aun-sdk/src/ownership_v21_backend.rs`:spawn_worker |
183
+ | 转让证书 | 导入前核对 `entity_cert_fingerprint` | `crates/aun-sdk/src/org_lifecycle.rs`:complete_org_transfer |
184
+ | 成员续期 | 按 §5.4 保存完整包、跳过短期、不误写组织账户 | `crates/aun-sdk/src/org_workflows.rs`:execute_org_workflow、renew_due_org_memberships、ensure_org_membership_fresh;`org_membership_package.rs`;`credential_org.rs`:current |
185
+ | 发布版本 | 同步 crate 与 `aun_types::SDK_VERSION`,envelope 复用常量 | `Cargo.toml`;`crates/aun-types/src/lib.rs` |
186
+
187
+ 保留 Rust 现有私钥丢失保护、completed 重放及直连 AID 名片读取。跨域发布/恢复用上传者所属域 token,并在该域刷新,由目标 NS 权威校验;保留原 pending/CAS。Python 共享目录和 Go 错误链修复仅在有对应路径时采用。
188
+
189
+ ## 8. 移植与验收顺序
190
+
191
+ | 顺序 | 验收要求 |
192
+ | --- | --- |
193
+ | 后台/群 | hint 不重置退避,前台可继续;终态联动停止和恢复;非 active 跳过,当前角色及 proposal 去重 |
194
+ | Ownership | 一次冲突重查、Stage 预检/响应、两种绑定、sub 离线、精确拒绝清理、原件变化、三类 CAS、丢响应、reset、晚订阅/背压 |
195
+ | 凭证组织 | 乱序合并、分页连续、旧代次丢弃、小时补拉;缺私钥/指纹不符保留现场;完成重放、无事件续期包、短期跳过 |
196
+ | 缓存 | 缺省及显式策略、65,536 字节边界、摘要/刷新/条件复用、失效、重启、淘汰、故障降级、三类查询回源、普通/权威 owner.md |
197
+ | 专项与互操作 | 对应语言修复、版本一致、NS 解锁投影及群错误行为 |
198
+
199
+ 测试入口与已执行范围见 [parity](../../python/CHANGES_FOR_PARITY.md)。缓存专项为 [16×4 矩阵](../../tests/cross-sdk/cases.storage-cache.json)/[runner](../../tests/cross-sdk/runner/run_storage_cache_e2e.py)、[Python E2E](../../python/tests/e2e_test_storage_cache.py)、[浏览器](../../js/tests/e2e-browser/storage.spec.ts)。联网按 [单域](../aun测试运行指南.md)/[公网](../aun公网测试运行指南.md)/[双域](../aun分布式测试运行指南.md) 执行,首失败修复后从该项续跑。
@@ -480,6 +480,8 @@ headers = client.get_protected_headers()
480
480
 
481
481
  Ownership 2.1 关系须检查当前双文件共识;Group/Org 使用专属生命周期,通用关系操作返回 `not_applicable`。Credential/Org 的本地验签不代替当前状态和请求授权检查。
482
482
 
483
+ sub-first 绑定在 sub 同意后 Stage 暂存 `agent.md`;NS 的 `pending/unlocked` 对公共共识映射为 `single_sided`,不授予 owner 权限,Storage 名片副本待 fresh 验收清除 pending 后同步。owner-first 绑定先 fresh 确认无锁并条件发布 `owner.md`,sub fresh 验证后同意并直接条件提交 `agent.md`,不走 Stage 或 bind.accept/owner.ready 往返。已有 owner 锁时只能由当前 owner 发起解绑或转移;拒绝清理与 reset 的原件/CAS 边界见 [应用指南 §6.1](Ownership2.1-SDK应用集成指南.md#61-绑定按发起方分流)。普通消息建议连接前订阅,READY 后补订阅也会触发任务恢复。
484
+
483
485
  ### 文件与存储门面
484
486
 
485
487
  | 能力 | Python | TS/JS | Go | 说明 |
@@ -492,6 +494,20 @@ Ownership 2.1 关系须检查当前双文件共识;Group/Org 使用专属生
492
494
 
493
495
  群文件系统路径统一使用 `group_aid:/...`,成员数据区使用 `group_aid:/memberdata/{member_ref}/...`。SDK 不拼接真实 storage 路径,`memberdata` 到成员 `group_data/{group_aid}` 的映射只在服务端完成。群自有区写入允许当前 `group_aid` 证书签名;成员角色中 `owner/admin` 默认可写群自有区,`member` 默认不可写。`owner/admin` 可通过 `group.fs.set_acl` 对特定业务目录授予 `role:member` 的 `rw` 权限,用于后续群协作场景;`rw` 只允许创建/写入,不授予删除、移动、重命名权限。`rwd` 是 storage 内部权限位,SDK/RPC 对外按 POSIX 视图显示为 `rwx`,不给删除/移动/重命名权限时只使用 `rw`。`.group/` 是系统控制目录,默认给 `owner/admin` 写权限,用于群公告、群规则、入群要求附件,不能向 `role:member` 授权。老群如果缺少 `.group/` 默认 ACL,group 服务会在该群首次被 RPC 访问时 best-effort 触发 namespace/ACL lazy repair;ACL 同步全部成功后才记录本进程已检查,失败会在后续访问继续重试。JS 浏览器版上传中 `string` 默认表示文本内容,Node 本地路径需显式 `sourceType: "path"`、`localPath: true` 或 `local:` 前缀;Python/TS/Go 默认把 `string` 当本地路径。
494
496
 
497
+ #### 默认读缓存与单次刷新
498
+
499
+ 四个 SDK 的 Storage / Group FS 读取默认由客户端决定缓存:响应未提供 `read_cache` 或值为 `null` 时,元数据默认缓存 60 秒;完整正文仅在实际大小不超过 65,536 字节且 SHA-256 校验通过时进入默认 inline 缓存。显式策略须 `reusable: true`,正文还须 `inline: true`;省略 `max_age_ms` 时默认 60 秒,有限正数最多使用 60 秒。显式禁止、null/非正数/非法 TTL 不复用。限次授权的 inline 读取仅返回正文时计次;inline 和大对象无正文 `not_modified` 均不计次,额度耗尽后仍允许匹配 SHA 的条件验证。SDK 本地缓存命中与 HEAD 等纯元数据查询不计次;撤销、过期、身份及权限检查保持。大对象按 URL 签发/授权 302 的下载授权计次,同 URL 有效期内复用属于同次授权,不统计外部 OSS 实际 GET 次数。
500
+
501
+ | 调用方 | 单次读取选项 | 语义 |
502
+ |--------|--------------|------|
503
+ | TypeScript / JavaScript | `noCache: true` | 跳过有效缓存命中,向远端重新校验 |
504
+ | Python | `no_cache=True` | 同上 |
505
+ | Go | 对应 VFS Options 的 `NoCache: true` | 同上 |
506
+
507
+ TS/JS 的底层 RPC 和 Group FS 也兼容 `no_cache: true`;TypeScript Storage VFS 的类型化选项使用 `noCache`。这些选项由 SDK 消费,不作为服务端业务参数发送。强制刷新可携带已有 `if_sha256`,远端确认未变化时继续使用已校验正文;新结果仍可写入缓存,不能把 `noCache` 当作 no-store。需要完整权威读取时,在支持该参数的底层 RPC 上使用 `consistency: "authoritative"`;该路径绕过 SDK 读缓存,也绕过服务端正负缓存。
508
+
509
+ 普通文件 API 读取 `owner.md` 同样遵循默认缓存规则。Ownership 管理维护及新鲜共识检查继续使用权威读取;`resolve` 的 ownership 快照是单独的展示缓存,其 `forceRefresh` / `ownershipTtlMs` 规则不变。完整的 `read_cache`、条件读取及范围见 [Storage RPC 手册](09-storage-rpc-manual.md#sdk-默认读缓存);Group FS 适用同一策略。
510
+
495
511
  ### 消息与群组门面
496
512
 
497
513
  | 能力 | Python | TS/JS | Go | 说明 |
@@ -1583,6 +1583,12 @@ SDK 只保证单个实时拉取响应页内按 seq 升序、同 seq 最多发布
1583
1583
  - 上传控制面会透传 `parents` 到 storage:默认 `parents=true` 时可递归创建父目录,显式 `parents=false` 时父目录必须已存在。
1584
1584
  - JavaScript 浏览器版 `cp(string, group)` 默认把 string 当文本内容上传;Node 本地路径需显式传 `sourceType: "path"`、`localPath: true` 或使用 `local:` 前缀。Python、TypeScript 和 Go 默认把 string 当本地路径。
1585
1585
 
1586
+ ### SDK 默认读缓存
1587
+
1588
+ 四个 SDK 的 Group FS 元数据查询与符合条件的完整下载正文复用 Storage 读缓存规则:服务端缺少或返回 `null` 的 `read_cache` 时默认缓存,元数据 TTL 为 60 秒,默认正文上限为 65,536 字节并校验 SHA-256。显式允许策略须 `reusable: true`,正文还须 `inline: true`;省略 `max_age_ms` 时默认 60 秒,有限正数最多使用 60 秒。显式禁止、null/非正数/非法 TTL 不复用。大正文不进入缺省 inline 缓存,Group 服务仍仅返回票据,由 SDK 完成 HTTP 下载。
1589
+
1590
+ 单次调用可用 TS/JS `noCache: true`(兼容 `no_cache`)、Python `no_cache=True` 或 Go 对应 Group FS Options 的 `NoCache: true` 强制远端校验。该选项由 SDK 消费,既有 SHA-256 仍可用于条件读取,新结果仍可缓存;它不等于 no-store。缓存按调用身份及群路径/参数隔离,群文件写入和 ACL 等相关变更继续触发失效。完整策略和条件读取说明见 [Storage RPC 手册](09-storage-rpc-manual.md#sdk-默认读缓存)。
1591
+
1586
1592
  ### group.fs.ls
1587
1593
 
1588
1594
  列出目录。参数:`path` 必填;可选 `page`、`size`、`marker`、`long`、`recursive`。响应返回 group view `items`,节点 `path` 仍为 group path。
@@ -1607,8 +1613,12 @@ SDK 只保证单个实时拉取响应页内按 seq 升序、同 seq 最多发布
1607
1613
 
1608
1614
  创建下载票据。参数:`path` 必填。响应包含 `url` / `download_url`、`expire_at`,以及可选的 `token`、`sha256`、`content_type`、`file_name`。私有文件和跨 issuer 文件由资源所在域签发短 TTL 的 `?t=` 能力凭据;Group 只返回票据,不代理文件字节。
1609
1615
 
1616
+ 还支持 `if_sha256`(string,64 位十六进制完整正文摘要)和 `consistency`;服务端向 Storage 传递这两个条件,响应可包含 `read_cache`(object)及 `not_modified`(boolean)。当前访问校验通过且摘要匹配时可只返回对象元数据,不签发新 URL/token;SDK 必须已有摘要匹配且验证通过的正文才能复用,否则重新申请完整票据。范围读取不复用普通完整正文缓存,`noCache`/`no_cache` 由 SDK 消费,不是本 RPC 的业务参数。字段类型及策略见 [Storage 条件读取](09-storage-rpc-manual.md#策略字段与条件读取)。
1617
+
1610
1618
  SDK Group FS 门面使用票据执行 HTTP GET 并校验 sha256。应用自行下载时遵守与 `storage.create_download_ticket` 相同的数据面规则:完整保留 URL 中的 `?t=`;只有端点明确要求 AID Bearer 时,才在每次请求前调用 Python `get_access_token()`、TypeScript / JavaScript `getAccessToken()` 或 Go `GetAccessToken()`;不得长期复用 `authenticate()` 首次返回的 token,也不得把当前域的 AID JWT 发送给另一 issuer 的 storage。401/403 仅在重新读取到不同 token 时重试一次;票据过期应重新申请。完整流程见 [Storage RPC 手册](09-storage-rpc-manual.md#数据面-http-下载流程)。
1611
1619
 
1620
+ Group FS 的读缓存保存符合策略的已验证正文,不把下载票据及其 token/URL 长期保存复用;热命中不联网,远端修改或撤权可能到刷新/TTL 到期才被观察,默认最多 60 秒。身份/网关隔离、写入及权限变更失效、持久后端、已对齐分支和验证边界见 [0.5.22 移植指南](0.5.22-SDK开发与移植指南.md#61-storage--group-fs-默认读缓存)。
1621
+
1612
1622
  ### group.fs.set_acl
1613
1623
 
1614
1624
  授予群自有区角色 ACL。需要当前 group `owner/admin` 身份调用;底层由 group 服务以内部门面写入 `storage.set_acl`。