@agentunion/fastaun-browser 0.5.3 → 0.5.6
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 +130 -56
- package/_packed_docs/AUN/347/246/273/347/272/277/346/216/250/351/200/201/346/216/245/345/205/245/344/270/216/346/274/224/347/244/272/346/214/207/345/215/227.md +290 -0
- package/_packed_docs/AUN/347/246/273/347/272/277/346/216/250/351/200/201/346/234/215/345/212/241/346/236/266/346/236/204/344/270/216/350/257/246/347/273/206/345/256/236/347/216/260/350/256/241/345/210/222-codex.md +994 -0
- package/_packed_docs/AUN/347/246/273/347/272/277/346/216/250/351/200/201/346/234/215/345/212/241/350/277/220/347/273/264/344/270/216/345/217/221/345/270/203/346/214/207/345/215/227.md +144 -0
- package/_packed_docs/CHANGELOG.md +130 -56
- package/_packed_docs/INDEX.md +127 -69
- package/_packed_docs/KITE_DOCS_GUIDE.md +63 -29
- package/_packed_docs/audit/AUN/346/234/215/345/212/241Go/345/214/226/351/207/215/346/236/204/347/262/276/347/273/206/345/214/226/346/272/220/347/240/201/345/256/241/346/237/245-20260718.md +366 -0
- package/_packed_docs/aun/345/205/254/347/275/221/346/265/213/350/257/225/350/277/220/350/241/214/346/214/207/345/215/227.md +227 -0
- 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 +1004 -0
- package/_packed_docs/aun/346/265/213/350/257/225/350/277/220/350/241/214/346/214/207/345/215/227.md +999 -0
- package/_packed_docs/cli/CLI/346/211/213/345/206/214.md +6 -4
- package/_packed_docs/protocol/06-/346/234/215/345/212/241/345/215/217/350/256/256.md +58 -20
- package/_packed_docs/protocol/10-Group-/345/255/220/345/215/217/350/256/256.md +219 -247
- package/_packed_docs/protocol/12-Stream-/345/255/220/345/215/217/350/256/256.md +14 -14
- package/_packed_docs/protocol/13-Agent/350/241/214/344/270/272/350/247/204/350/214/203.md +3 -3
- package/_packed_docs/protocol/15-/347/246/273/347/272/277/346/216/250/351/200/201/351/200/232/347/237/245/345/215/217/350/256/256.md +165 -421
- package/_packed_docs/protocol/README.md +1 -0
- package/_packed_docs/protocol/aun-docs-guide.md +7 -4
- package/_packed_docs/protocol/index.md +25 -19
- package/_packed_docs/sdk/02-WebSocket/345/215/217/350/256/256.md +62 -17
- package/_packed_docs/sdk/03-/346/240/270/345/277/203/346/246/202/345/277/265.md +22 -0
- package/_packed_docs/sdk/04-/350/277/236/346/216/245/344/270/216/350/256/244/350/257/201.md +67 -78
- package/_packed_docs/sdk/05-E2EE/345/212/240/345/257/206/351/200/232/344/277/241.md +6 -2
- package/_packed_docs/sdk/06-API/346/211/213/345/206/214.md +87 -41
- package/_packed_docs/sdk/08-/346/234/200/344/275/263/345/256/236/350/267/265.md +18 -5
- package/_packed_docs/sdk/09-group-rpc-manual.md +307 -267
- package/_packed_docs/sdk/09-message-rpc-manual.md +142 -103
- package/_packed_docs/sdk/09-payload-reference.md +1 -1
- package/_packed_docs/sdk/09-stream-rpc-manual.md +8 -8
- package/_packed_docs/sdk/AUN_DOCS_GUIDE.md +26 -17
- package/_packed_docs/sdk/INDEX.md +42 -34
- package/_packed_docs/sdk/README.md +7 -6
- 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 +229 -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/346/224/271/351/200/240/346/226/271/346/241/210.md +750 -0
- package/dist/agent-md.d.ts +4 -5
- package/dist/agent-md.d.ts.map +1 -1
- package/dist/agent-md.js +66 -43
- package/dist/agent-md.js.map +1 -1
- package/dist/aid-store.d.ts +2 -6
- package/dist/aid-store.d.ts.map +1 -1
- package/dist/aid-store.js +20 -14
- package/dist/aid-store.js.map +1 -1
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +30 -11
- package/dist/auth.js.map +1 -1
- package/dist/bundle.js +3399 -1069
- package/dist/client/delivery.d.ts +75 -8
- package/dist/client/delivery.d.ts.map +1 -1
- package/dist/client/delivery.js +1419 -245
- package/dist/client/delivery.js.map +1 -1
- package/dist/client/group-state.d.ts.map +1 -1
- package/dist/client/group-state.js +27 -24
- package/dist/client/group-state.js.map +1 -1
- package/dist/client/lifecycle.d.ts.map +1 -1
- package/dist/client/lifecycle.js +48 -4
- package/dist/client/lifecycle.js.map +1 -1
- package/dist/client/mention-mode.d.ts +7 -0
- package/dist/client/mention-mode.d.ts.map +1 -0
- package/dist/client/mention-mode.js +184 -0
- package/dist/client/mention-mode.js.map +1 -0
- package/dist/client/peers.d.ts +1 -1
- package/dist/client/peers.d.ts.map +1 -1
- package/dist/client/peers.js +26 -3
- package/dist/client/peers.js.map +1 -1
- package/dist/client/rpc-pipeline.d.ts +22 -1
- package/dist/client/rpc-pipeline.d.ts.map +1 -1
- package/dist/client/rpc-pipeline.js +309 -74
- package/dist/client/rpc-pipeline.js.map +1 -1
- package/dist/client/v2-e2ee.d.ts +25 -2
- package/dist/client/v2-e2ee.d.ts.map +1 -1
- package/dist/client/v2-e2ee.js +606 -97
- package/dist/client/v2-e2ee.js.map +1 -1
- package/dist/client.d.ts +24 -5
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +404 -215
- package/dist/client.js.map +1 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +4 -1
- package/dist/errors.js.map +1 -1
- package/dist/facades.d.ts +6 -0
- package/dist/facades.d.ts.map +1 -1
- package/dist/facades.js +199 -104
- package/dist/facades.js.map +1 -1
- package/dist/group-index.d.ts +6 -1
- package/dist/group-index.d.ts.map +1 -1
- package/dist/group-index.js +44 -25
- package/dist/group-index.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/keystore/index.d.ts +10 -5
- package/dist/keystore/index.d.ts.map +1 -1
- package/dist/keystore/indexeddb-identity-store.d.ts +0 -12
- package/dist/keystore/indexeddb-identity-store.d.ts.map +1 -1
- package/dist/keystore/indexeddb-identity-store.js +0 -60
- package/dist/keystore/indexeddb-identity-store.js.map +1 -1
- package/dist/keystore/indexeddb-shared.d.ts.map +1 -1
- package/dist/keystore/indexeddb-shared.js +9 -5
- package/dist/keystore/indexeddb-shared.js.map +1 -1
- package/dist/keystore/indexeddb-token-store.d.ts +3 -1
- package/dist/keystore/indexeddb-token-store.d.ts.map +1 -1
- package/dist/keystore/indexeddb-token-store.js +47 -2
- package/dist/keystore/indexeddb-token-store.js.map +1 -1
- package/dist/register-flow.d.ts.map +1 -1
- package/dist/register-flow.js +28 -3
- package/dist/register-flow.js.map +1 -1
- package/dist/seq-tracker.d.ts +28 -8
- package/dist/seq-tracker.d.ts.map +1 -1
- package/dist/seq-tracker.js +218 -61
- package/dist/seq-tracker.js.map +1 -1
- package/dist/storage/vfs.d.ts +1 -0
- package/dist/storage/vfs.d.ts.map +1 -1
- package/dist/storage/vfs.js +26 -2
- package/dist/storage/vfs.js.map +1 -1
- package/dist/tools/cross-sdk-agent.js +376 -10
- package/dist/tools/cross-sdk-agent.js.map +1 -1
- package/dist/transport.d.ts +12 -0
- package/dist/transport.d.ts.map +1 -1
- package/dist/transport.js +218 -101
- package/dist/transport.js.map +1 -1
- package/dist/v2/session/session.d.ts.map +1 -1
- package/dist/v2/session/session.js +3 -4
- package/dist/v2/session/session.js.map +1 -1
- package/dist/v2/state/commitment.d.ts.map +1 -1
- package/dist/v2/state/commitment.js +1 -2
- package/dist/v2/state/commitment.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +6 -5
- package/dist/group-resources.d.ts +0 -98
- package/dist/group-resources.d.ts.map +0 -1
- package/dist/group-resources.js +0 -635
- package/dist/group-resources.js.map +0 -1
- package/dist/keystore/indexeddb.d.ts +0 -179
- package/dist/keystore/indexeddb.d.ts.map +0 -1
- package/dist/keystore/indexeddb.js +0 -2031
- package/dist/keystore/indexeddb.js.map +0 -1
- package/dist/namespaces/auth.d.ts +0 -98
- package/dist/namespaces/auth.d.ts.map +0 -1
- package/dist/namespaces/auth.js +0 -992
- package/dist/namespaces/auth.js.map +0 -1
- package/dist/namespaces/custody.d.ts +0 -51
- package/dist/namespaces/custody.d.ts.map +0 -1
- package/dist/namespaces/custody.js +0 -302
- package/dist/namespaces/custody.js.map +0 -1
- package/dist/namespaces/meta.d.ts +0 -109
- package/dist/namespaces/meta.d.ts.map +0 -1
- package/dist/namespaces/meta.js +0 -549
- package/dist/namespaces/meta.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,75 +6,149 @@
|
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
-
## 0.5.
|
|
9
|
+
## 0.5.6 — 2026-08-13
|
|
10
10
|
|
|
11
11
|
### 新功能
|
|
12
12
|
|
|
13
|
-
####
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
- 入口导出 `GROUP_INDEX_KEY`、`GROUP_INDEX_SCHEMA`、`GroupIndexMetaCache`、`buildSignedGroupIndex`、`verifyGroupIndex`、`prepareGroupSettingsWithIndex` 等 group.index API。
|
|
13
|
+
#### V2 消息窗口与实时推送
|
|
14
|
+
- 完成 `tail` / `forward` / `history` 消息窗口、IndexedDB seq 状态持久化和 pull gate 调度,统一 P2P 与群消息的补洞、确认和有序投递。
|
|
15
|
+
- 连接认证时声明 `inline_realtime_payload_v1`;实时事件优先使用内联消息载荷,离线或不完整事件继续通过 pull 回退。
|
|
16
|
+
- 对齐 Message/Group self-sync 与 bootstrap 契约,补齐浏览器多设备同步状态处理。
|
|
18
17
|
|
|
19
|
-
|
|
18
|
+
#### 群消息提及过滤
|
|
19
|
+
- 新增 `mention_mode` 归一化与投递过滤,兼容 `disabled`、`mention-only` 及历史 `mention_only` 表示。
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
- `message.recalled` 改为专用处理路径,支持 P2P 撤回 tombstone 的有序投递、自动 ack、gap fill 和按原消息标识去重,避免 push / pull 对同一次撤回重复回调。
|
|
23
|
-
- 群撤回去重键改为规范化 group id + 原消息 id/seq,忽略 `recalled_at`,并补齐顶层 recall 字段归一化。
|
|
24
|
-
- 群消息 pull / legacy fallback 识别 `group.message_recalled` tombstone,避免把撤回通知作为普通群消息投递。
|
|
25
|
-
- P2P 与群 push 按 namespace 串行化处理,降低异步解密和投递导致的乱序风险。
|
|
26
|
-
- V2 P2P / Group pull 页内消息按 `seq` 排序后处理,避免服务端返回无序时影响本地 seq 推进。
|
|
21
|
+
### 安全性
|
|
27
22
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
-
|
|
31
|
-
- `getAnnouncement` / `getRules` / `getJoinRequirements` 优先使用 group.index settings cache;`updateAnnouncement` / `updateRules` / `updateJoinRequirements` 改走 `updateGroupIndex`,保持索引与设置同步。
|
|
32
|
-
- cross-sdk JS agent 支持 `sdk.update_group_index` 调用,便于跨 SDK 测试索引化群设置。
|
|
33
|
-
- SDK 包版本、运行时 `VERSION` 和 conformance 期望版本更新为 `0.5.3`。
|
|
34
|
-
|
|
35
|
-
### 测试
|
|
36
|
-
|
|
37
|
-
- 新增 group.index 单元测试,覆盖 hash/etag、签名/验签、settings merge、RPC meta stale/fresh、async meta observer 和 IndexedDB 持久化恢复。
|
|
38
|
-
- 新增 GroupFacade group.index 单元测试,覆盖 CAS 写入、冲突重试、远端索引验签、tamper 拒绝、settings cache 和便利方法索引化写入。
|
|
39
|
-
- 新增浏览器 E2E:验证签名 `group.index` 写入、裸 settings 写入拒绝、CAS 冲突重试和最终 settings 一致性。
|
|
40
|
-
- 扩展撤回投递测试,覆盖 P2P/group recall 顶层字段归一化、push/pull tombstone 去重和有序投递。
|
|
41
|
-
- 更新 group settings 与签名审计 E2E,使公告/群规等索引化 settings 通过 `updateGroupIndex` 写入。
|
|
42
|
-
|
|
43
|
-
---
|
|
44
|
-
|
|
45
|
-
## 0.5.2 — 2026-07-05
|
|
46
|
-
|
|
47
|
-
### 新功能
|
|
48
|
-
|
|
49
|
-
#### agent.md 元数据
|
|
50
|
-
- 支持从 RPC `_meta.agent_md_etags.group` 和 V2 envelope `agent_md.group` 观察群组 agent.md ETag / Last-Modified,并自动维护群 AID 的本地缓存。
|
|
51
|
-
- 群消息 agent.md 观察逻辑补齐 sender / group 两类来源,提升浏览器端跨设备、跨群消息场景下的版本一致性提示能力。
|
|
52
|
-
|
|
53
|
-
### 修复
|
|
54
|
-
|
|
55
|
-
#### V2 P2P / Group 拉取
|
|
56
|
-
- `message.v2.pull` / `group.v2.pull` 自动 ack 改为通过下一次 pull 的 `ack_up_to_seq` piggyback,减少独立 ack RPC。
|
|
57
|
-
- 修复非满页返回 `has_more=true` 时盲目续拉的问题;满页继续立即拉,非满页仅在有待合并 ack 时追加一页。
|
|
58
|
-
- 过滤 `seq <= after_seq` 的 stale 原始消息,避免重复处理或错误推进 ack。
|
|
59
|
-
- stale 原始页未推进 contiguous seq 时不再发送自动 ack,避免把未真正拉齐的数据误确认。
|
|
23
|
+
- `lookupPeer()` 在内存 peer cache 未命中或指纹不匹配时自动获取并校验证书;支持按签名指纹精确加载历史证书。
|
|
24
|
+
- `group.index` 和 `agent.md` 在下载或更新提交 IndexedDB 缓存前验签;rules、announcement、join requirements 等索引化 settings 逐项校验已签名索引中的 ETag。签名者权限、摘要或内容校验失败时不落盘,也不参与业务读取;已验证缓存的普通读取不重复验签。
|
|
25
|
+
- 修复跨域 Storage 下载的 bearer 隔离,并加固浏览器连接/重连及 Gateway 候选故障转移。
|
|
60
26
|
|
|
61
27
|
### 改进
|
|
62
28
|
|
|
63
|
-
-
|
|
64
|
-
-
|
|
65
|
-
-
|
|
29
|
+
- 收口短 RPC、challenge/response、前置帧和浏览器 transport 竞态;后台补洞/ack 调度不再阻塞前台 RPC。
|
|
30
|
+
- 扩展浏览器 cross-SDK agent 与诊断契约,覆盖消息窗口和 inline realtime 场景;浏览器 SDK 本版本未新增离线 Push facade。
|
|
31
|
+
- 浏览器使用 IndexedDB keystore,不适用文件型 `.seed` 自动迁移;不新增文件型 `change-seed` 命令。
|
|
32
|
+
- SDK 包版本、运行时 `VERSION` 和 conformance 期望版本更新为 `0.5.6`。
|
|
66
33
|
|
|
67
34
|
### 测试
|
|
68
35
|
|
|
69
|
-
-
|
|
70
|
-
-
|
|
71
|
-
- 扩展 agent.md 和 conformance 测试,覆盖群组 ETag 观察及 0.5.2 版本声明。
|
|
36
|
+
- 新增消息窗口、inline realtime push、mention mode、self-sync/bootstrap、peer identity、group index、`agent.md` 和 IndexedDB/浏览器 E2E 测试。
|
|
37
|
+
- 扩展 cross-SDK contract vectors,覆盖验签后缓存提交和窗口状态一致性。
|
|
72
38
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
39
|
+
## 0.5.5 — 2026-07-14
|
|
40
|
+
|
|
41
|
+
### 维护
|
|
42
|
+
|
|
43
|
+
- SDK 包版本、运行时 `VERSION` 和 conformance 期望版本更新为 `0.5.5`。
|
|
44
|
+
|
|
45
|
+
## 0.5.4 — 2026-07-09
|
|
46
|
+
|
|
47
|
+
### 新功能
|
|
48
|
+
|
|
49
|
+
#### 通用 indexed document settings
|
|
50
|
+
- 浏览器 `GroupFacade` 新增 `getSettingWithIndex()` / `updateSettingWithIndex()`,支持按 `keyName` 管理 `{keyName}.content` 与 `{keyName}.attachments` 两类文档型 indexed settings。
|
|
51
|
+
- `keyName` 增加统一校验:必须匹配 `^[A-Za-z][A-Za-z0-9_-]{0,63}$`,并拒绝 `join`、`group`、`index`、`visibility` 等保留基名。
|
|
52
|
+
- `getAnnouncement()` / `updateAnnouncement()` 与 `getRules()` / `updateRules()` 复用通用 indexed document setting 路径,继续通过 signed `group.index` + `expected_index_etag` CAS 写入。
|
|
53
|
+
|
|
54
|
+
#### 入群要求附件
|
|
55
|
+
- `getJoinRequirements()` / `updateJoinRequirements()` 支持 `attachments`,对应服务端 `join.attachments` indexed setting。
|
|
56
|
+
- `join.attachments` 与公告/群规附件保持同一类 `group.fs` 引用结构,可通过 group.index 签名索引同步。
|
|
57
|
+
|
|
58
|
+
#### Group FS 角色 ACL
|
|
59
|
+
- 服务端 group.fs 命名空间新增受保护 `.group` 控制目录,并为 owner/admin 同步基线角色 ACL。
|
|
60
|
+
- owner/admin 默认可写群自有区;admin 可管理群自有区角色 ACL。
|
|
61
|
+
- `role:member` 支持按具体业务目录授予 `rw`,允许成员创建/上传,但不允许删除、重命名或移动群自有区内容。
|
|
62
|
+
|
|
63
|
+
### 修复
|
|
64
|
+
|
|
65
|
+
- 修复 Storage 直接入口对群自有区删除/移动/重命名权限检查不足的问题,删除类操作统一走 `delete` 权限判定。
|
|
66
|
+
- 修复旧 group AID 证书类型仍为 normal 时,Storage 无法通过 group resolver 判定群空间的问题。
|
|
67
|
+
- 兼容 CA 续期时 PEM 公钥与 SPKI base64 的等价比较,并兼容托管续期返回 `cert_pem` / `new_cert` 字段。
|
|
68
|
+
|
|
69
|
+
### 改进
|
|
70
|
+
|
|
71
|
+
- message/group WAL writer 的 `micro_wait` 支持 auto 预算模型,并扩展性能统计输出,便于观察批量写入队列深度与 pending 状态。
|
|
72
|
+
- group.fs 命名空间在读取 group 记录时支持懒修复,缺失 baseline ACL 时可重试同步。
|
|
73
|
+
- SDK 包版本、运行时 `VERSION` 和 conformance 期望版本更新为 `0.5.4`。
|
|
74
|
+
|
|
75
|
+
### 测试
|
|
76
|
+
|
|
77
|
+
- 扩展浏览器 GroupFacade group index 单元测试,覆盖通用 indexed document setting、`join.attachments` 缓存读取和 group.index 写入路径。
|
|
78
|
+
- 更新 conformance 版本期望到 `0.5.4`。
|
|
79
|
+
- 服务端测试扩展 group settings、group.fs namespace / role ACL、Storage 群自有区权限和 CA 续期兼容性。
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## 0.5.3 — 2026-07-07
|
|
84
|
+
|
|
85
|
+
### 新功能
|
|
86
|
+
|
|
87
|
+
#### group.index 索引化群设置
|
|
88
|
+
- 新增浏览器 `group.index` JSONL 工具:支持 canonical entries、body hash、etag、ECDSA P-256 签名/验签,以及将 settings 更新合并为带 `group.index` 的原子写入。
|
|
89
|
+
- `GroupFacade` 新增 `checkGroupIndex` / `getGroupIndex` / `updateGroupIndex`,写入时携带 `expected_index_etag` 做 CAS,并在冲突后重拉索引重试。
|
|
90
|
+
- 浏览器 IndexedDB TokenStore 新增 `group_index_cache`,按 local AID + group AID 持久化 index JSONL、remote meta、本地 etag、settings cache 和 entry etags。
|
|
91
|
+
- 入口导出 `GROUP_INDEX_KEY`、`GROUP_INDEX_SCHEMA`、`GroupIndexMetaCache`、`buildSignedGroupIndex`、`verifyGroupIndex`、`prepareGroupSettingsWithIndex` 等 group.index API。
|
|
92
|
+
|
|
93
|
+
### 修复
|
|
94
|
+
|
|
95
|
+
#### 撤回去重与有序投递
|
|
96
|
+
- `message.recalled` 改为专用处理路径,支持 P2P 撤回 tombstone 的有序投递、自动 ack、gap fill 和按原消息标识去重,避免 push / pull 对同一次撤回重复回调。
|
|
97
|
+
- 群撤回去重键改为规范化 group id + 原消息 id/seq,忽略 `recalled_at`,并补齐顶层 recall 字段归一化。
|
|
98
|
+
- 群消息 pull / legacy fallback 识别 `group.message_recalled` tombstone,避免把撤回通知作为普通群消息投递。
|
|
99
|
+
- P2P 与群 push 按 namespace 串行化处理,降低异步解密和投递导致的乱序风险。
|
|
100
|
+
- V2 P2P / Group pull 页内消息按 `seq` 排序后处理,避免服务端返回无序时影响本地 seq 推进。
|
|
101
|
+
|
|
102
|
+
### 改进
|
|
103
|
+
|
|
104
|
+
- `RPCTransport` 的 `_meta` observer 支持异步回调;RPC 成功响应会等待 observer 完成,事件/通知路径统一走安全的 meta observer 分发。
|
|
105
|
+
- `getAnnouncement` / `getRules` / `getJoinRequirements` 优先使用 group.index settings cache;`updateAnnouncement` / `updateRules` / `updateJoinRequirements` 改走 `updateGroupIndex`,保持索引与设置同步。
|
|
106
|
+
- cross-sdk JS agent 支持 `sdk.update_group_index` 调用,便于跨 SDK 测试索引化群设置。
|
|
107
|
+
- SDK 包版本、运行时 `VERSION` 和 conformance 期望版本更新为 `0.5.3`。
|
|
108
|
+
|
|
109
|
+
### 测试
|
|
110
|
+
|
|
111
|
+
- 新增 group.index 单元测试,覆盖 hash/etag、签名/验签、settings merge、RPC meta stale/fresh、async meta observer 和 IndexedDB 持久化恢复。
|
|
112
|
+
- 新增 GroupFacade group.index 单元测试,覆盖 CAS 写入、冲突重试、远端索引验签、tamper 拒绝、settings cache 和便利方法索引化写入。
|
|
113
|
+
- 新增浏览器 E2E:验证签名 `group.index` 写入、裸 settings 写入拒绝、CAS 冲突重试和最终 settings 一致性。
|
|
114
|
+
- 扩展撤回投递测试,覆盖 P2P/group recall 顶层字段归一化、push/pull tombstone 去重和有序投递。
|
|
115
|
+
- 更新 group settings 与签名审计 E2E,使公告/群规等索引化 settings 通过 `updateGroupIndex` 写入。
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## 0.5.2 — 2026-07-05
|
|
120
|
+
|
|
121
|
+
### 新功能
|
|
122
|
+
|
|
123
|
+
#### agent.md 元数据
|
|
124
|
+
- 支持从 RPC `_meta.agent_md_etags.group` 和 V2 envelope `agent_md.group` 观察群组 agent.md ETag / Last-Modified,并自动维护群 AID 的本地缓存。
|
|
125
|
+
- 群消息 agent.md 观察逻辑补齐 sender / group 两类来源,提升浏览器端跨设备、跨群消息场景下的版本一致性提示能力。
|
|
126
|
+
|
|
127
|
+
### 修复
|
|
128
|
+
|
|
129
|
+
#### V2 P2P / Group 拉取
|
|
130
|
+
- `message.v2.pull` / `group.v2.pull` 自动 ack 改为通过下一次 pull 的 `ack_up_to_seq` piggyback,减少独立 ack RPC。
|
|
131
|
+
- 修复非满页返回 `has_more=true` 时盲目续拉的问题;满页继续立即拉,非满页仅在有待合并 ack 时追加一页。
|
|
132
|
+
- 过滤 `seq <= after_seq` 的 stale 原始消息,避免重复处理或错误推进 ack。
|
|
133
|
+
- stale 原始页未推进 contiguous seq 时不再发送自动 ack,避免把未真正拉齐的数据误确认。
|
|
134
|
+
|
|
135
|
+
### 改进
|
|
136
|
+
|
|
137
|
+
- V2 pull 默认/最大 page limit 收敛为 50,并对传入 `limit` 做 1..50 夹取。
|
|
138
|
+
- V2 pull 增加非满页 tail delay:`1000ms / (pulled_messages + 1)`,最大 500ms;满页和空页仍立即结束或续拉。
|
|
139
|
+
- SDK 包版本、运行时 `VERSION` 和 conformance 期望版本更新为 `0.5.2`。
|
|
140
|
+
|
|
141
|
+
### 测试
|
|
142
|
+
|
|
143
|
+
- 扩展 V2 P2P / Group pull 单元测试,覆盖 `ack_up_to_seq` piggyback、非满页 tail delay、stale 过滤和 max pages flush。
|
|
144
|
+
- 新增 `v2-e2ee-coordinator` 组件边界测试,验证自动 ack 通过下一页 pull piggyback。
|
|
145
|
+
- 扩展 agent.md 和 conformance 测试,覆盖群组 ETag 观察及 0.5.2 版本声明。
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## 0.5.1 — 2026-07-01
|
|
150
|
+
|
|
151
|
+
### ⚠️ 重大变更(Breaking Changes)
|
|
78
152
|
|
|
79
153
|
#### 群组标识符统一为 GROUP_AID
|
|
80
154
|
- **GROUP_ID 废弃**:历史 `group.{domain}/{base}` 格式已废弃,统一为 `{base}.{issuer}` 格式(group_aid)
|
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
# AUN 离线推送接入与演示指南
|
|
2
|
+
|
|
3
|
+
本文面向应用开发者和 Push Server 实现者,说明如何接入当前 AUN Offline Push V1,并给出基于 Python SDK 与 Mock Push Server 的隔离演示路径。
|
|
4
|
+
|
|
5
|
+
> 当前结论:客户端和隔离 PoC 已可接入;生产发布仍受 push token 加密硬门阻断。本文中的明文 token、Mock 控制 API 和 Compose 演示不得用于生产。
|
|
6
|
+
|
|
7
|
+
## 1. 先分清三个“推送”角色
|
|
8
|
+
|
|
9
|
+
| 角色 | 负责什么 | 不负责什么 |
|
|
10
|
+
| --- | --- | --- |
|
|
11
|
+
| 终端客户端 | 向 Push Server 获取 opaque token;向 AUN 登记;被平台唤醒后重新连接并 pull | 不订阅 `push.offline_message` |
|
|
12
|
+
| Push Server | 签发并验证 opaque token;接收 AUN 离线批次;调用 APNs、FCM 或 WebPush;幂等处理并 ACK | 不保存或解析 AUN 消息正文 |
|
|
13
|
+
| AUN Push Service | 保存 registration、candidate、delivery 和 batch;判断在线状态;调度、重试和恢复 | 不直接调用 APNs、FCM 或 WebPush |
|
|
14
|
+
|
|
15
|
+
Gateway 只负责可信身份注入、Session 查询和定向路由。它不保存 `push_notify_aid`,不解析 token,也不与 Push Service 共享 registration Redis 缓存。
|
|
16
|
+
|
|
17
|
+
### 端到端时序
|
|
18
|
+
|
|
19
|
+
```mermaid
|
|
20
|
+
sequenceDiagram
|
|
21
|
+
participant App as 终端应用
|
|
22
|
+
participant PNS as Push Server
|
|
23
|
+
participant GW as Gateway
|
|
24
|
+
participant PS as Push Service
|
|
25
|
+
participant MSG as Message / Group
|
|
26
|
+
App->>PNS: 提交平台 token 和安装身份
|
|
27
|
+
PNS-->>App: opaque push_token
|
|
28
|
+
App->>GW: connect(long)
|
|
29
|
+
App->>PS: SDK 自动 push.register
|
|
30
|
+
MSG->>PS: 消息提交后 push.enqueue
|
|
31
|
+
PS->>GW: query_sessions(long_only=true)
|
|
32
|
+
PS->>PNS: push.offline_message(目标离线时)
|
|
33
|
+
PNS->>PNS: delivery_id 幂等 + 平台推送
|
|
34
|
+
PNS->>PS: push.ack(batch_id, status)
|
|
35
|
+
PNS-->>App: APNs / FCM / WebPush 唤醒
|
|
36
|
+
App->>GW: reconnect + message.pull / group.pull
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
真正的消息正文始终由原有 AUN 消息链路保存和拉取。离线推送只是允许丢失、可重试的“回来取消息”提示,失败不能改变消息发送成功语义。
|
|
40
|
+
|
|
41
|
+
## 2. 当前 V1 边界
|
|
42
|
+
|
|
43
|
+
- Python SDK 已提供 `connect()` 自动登记和 `client.push.register/unregister/ack`;Go、TypeScript、JavaScript SDK 尚无专用 Push facade。
|
|
44
|
+
- `push.offline_message` 只投递给 Push Server 的 AUN 长连接,不投递给普通终端,也不跨 federation。
|
|
45
|
+
- 在线判断以目标 AID 的长连接为准;只要查询到长连接在线,就抑制当前候选。查询失败或超时表示“未知”,不会被当成离线。
|
|
46
|
+
- V1 是单 Push Service、单可用 Gateway、批次级 ACK;不支持逐 delivery ACK。
|
|
47
|
+
- 多条 Push Server 长连接存在时,Push Service 确定性选择最早建立的一条;短连接不能承载离线批次。
|
|
48
|
+
- 当前实现只支持 `plaintext` token mode,且生产环境会拒绝以该模式启动。
|
|
49
|
+
|
|
50
|
+
## 3. 终端客户端接入
|
|
51
|
+
|
|
52
|
+
### 3.1 获取 opaque token
|
|
53
|
+
|
|
54
|
+
AUN 不规定“终端向 Push Server 换取 token”的 HTTP API。生产 Push Server 应自行提供受认证接口,完成以下工作:
|
|
55
|
+
|
|
56
|
+
1. 接收 APNs、FCM 或 WebPush 的原生设备凭据。
|
|
57
|
+
2. 确认请求者有权绑定当前 `aid/device_id/slot_id`。
|
|
58
|
+
3. 在服务端保存平台凭据和安装映射。
|
|
59
|
+
4. 返回有过期时间、可轮换、可吊销的 opaque `push_token`。
|
|
60
|
+
|
|
61
|
+
token 必须至少绑定目标 AID、device 和 slot,Push Server 收到批次后需用这三项重新验证。AUN Gateway 和 Push Service 均不会验证 token 的业务内容。
|
|
62
|
+
|
|
63
|
+
### 3.2 建连时登记
|
|
64
|
+
|
|
65
|
+
Python SDK 推荐在首次连接时完成登记:
|
|
66
|
+
|
|
67
|
+
```python
|
|
68
|
+
await client.connect({
|
|
69
|
+
"connection_kind": "long",
|
|
70
|
+
"auto_reconnect": True,
|
|
71
|
+
"push_notify_aid": "push.example.com",
|
|
72
|
+
"push_token": token,
|
|
73
|
+
"push_provider": "fcm",
|
|
74
|
+
"push_app_id": "com.example.app",
|
|
75
|
+
})
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
`push_notify_aid` 是应用和 SDK 的名称;SDK 在线上 RPC 中会映射为冻结字段 `push_server_aid`。`push_notify_aid` 与 `push_token` 必须同时提供。
|
|
79
|
+
|
|
80
|
+
SDK 会先建立 AUN 会话,再调用 `push.register`。只有登记成功后连接才进入 READY;登记失败会关闭本次 transport、停止后台任务并向调用方抛错,不会留下“已连接但未登记”的半成功状态。
|
|
81
|
+
|
|
82
|
+
安装身份只取 Gateway 注入的当前 `aid/device_id/slot_id`。应用不能在请求中伪造另一个 AID、device 或 slot。
|
|
83
|
+
|
|
84
|
+
### 3.3 token 轮换和注销
|
|
85
|
+
|
|
86
|
+
原生平台 token 变化、opaque token 临近过期或切换 Push Server 时,无需断开 AUN:
|
|
87
|
+
|
|
88
|
+
```python
|
|
89
|
+
await client.push.register(push_notify_aid="push.example.com", push_token=new_token)
|
|
90
|
+
await client.push.unregister()
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
- 重复 `register()` 更新当前安装,`registration_version` 递增并重新启用。
|
|
94
|
+
- `unregister()` 幂等返回 `status=disabled`,不删除历史 delivery。
|
|
95
|
+
- 退出账号、关闭推送权限或解除当前安装时,应在仍有连接的情况下主动注销。
|
|
96
|
+
|
|
97
|
+
### 3.4 被平台唤醒后
|
|
98
|
+
|
|
99
|
+
终端收到的是 Push Server 发出的原生平台通知,不是 AUN 的 `push.offline_message` 事件。通知 payload 只应表达“有新内容”,不得携带消息正文或 E2EE 密文。
|
|
100
|
+
|
|
101
|
+
应用被唤醒后重新建立 AUN 长连接,然后使用既有后台同步或显式 `message.pull` / `group.pull` 获取真实消息。消息去重、解密和 ACK 仍按原有 SDK 规则执行,不以平台通知次数作为消息计数真源。
|
|
102
|
+
|
|
103
|
+
## 4. Push Server 接入
|
|
104
|
+
|
|
105
|
+
### 4.1 AUN 身份和长连接
|
|
106
|
+
|
|
107
|
+
Push Server 必须使用预先签发、与 issuer 同域、已加入 `AUN_PUSH_ALLOWED_SERVER_AIDS` 的服务 AID。它是普通 AUN 客户端,不需要为自己调用 `push.register`。下面只展示连接结构,`ProductionPushServer` 由接入方实现:
|
|
108
|
+
|
|
109
|
+
```python
|
|
110
|
+
client = AUNClient(push_server_identity)
|
|
111
|
+
server = ProductionPushServer(client, provider, durable_store)
|
|
112
|
+
client.on("push.offline_message", server.handle_event)
|
|
113
|
+
await client.connect({"connection_kind": "long", "auto_reconnect": True})
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
服务端进程需要在 SDK 自动重连之外提供应用层存活守护。认证类终止关闭码可能停止 SDK 内部自动重连,常驻服务应在 SDK 已进入离线终态后重新调用 `connect()`,同时避免并发建立多条连接。
|
|
117
|
+
|
|
118
|
+
### 4.2 token 服务
|
|
119
|
+
|
|
120
|
+
生产 token 服务至少应具备:
|
|
121
|
+
|
|
122
|
+
- 调用方认证和安装所有权校验;不能只信任客户端自报的 AID。
|
|
123
|
+
- 原生平台 token 的加密存储、轮换、吊销和过期处理。
|
|
124
|
+
- opaque token 的签名或随机引用,不暴露原生平台凭据。
|
|
125
|
+
- 对 `(target_aid, device_id, slot_id)` 的强绑定和恒定时间签名比较。
|
|
126
|
+
- 限流、审计和敏感字段脱敏;日志只记录不可逆短指纹。
|
|
127
|
+
|
|
128
|
+
Mock Push Server 使用 HMAC token 展示这些语义,但它不是生产凭据方案。
|
|
129
|
+
|
|
130
|
+
### 4.3 批次处理顺序
|
|
131
|
+
|
|
132
|
+
收到 `push.offline_message` 后必须按以下顺序处理:
|
|
133
|
+
|
|
134
|
+
1. 校验 `protocol_version=1`、64 位十六进制 `batch_id`、`expires_at_ms` 和 items 数量。
|
|
135
|
+
2. 对每个 item 校验必填字段,并验证 token 与 `target_aid/device_id/slot_id` 一致且未过期。
|
|
136
|
+
3. 在持久存储中以 `delivery_id` 建立幂等记录;不可变字段冲突必须拒绝。
|
|
137
|
+
4. 仅对首次处理的 delivery 调用 APNs、FCM 或 WebPush;重复批次不得重复不可逆副作用。
|
|
138
|
+
5. 先持久化平台调用结果,再计算整个 batch 的 ACK 状态。
|
|
139
|
+
6. 调用 `client.push.ack(batch_id=..., status=...)`。
|
|
140
|
+
7. ACK 调用结果未知时允许用相同 batch/status 重试;重复事件到达时仍需再次 ACK。
|
|
141
|
+
|
|
142
|
+
平台接受请求只表示 Push Server 已接管通知,不表示用户设备已经展示或读取消息。
|
|
143
|
+
|
|
144
|
+
### 4.4 批次级 ACK
|
|
145
|
+
|
|
146
|
+
| status | Push Service 行为 | Push Server 使用条件 |
|
|
147
|
+
| --- | --- | --- |
|
|
148
|
+
| `accepted` | batch 内 delivery 进入 accepted | 全批已被平台接受或已幂等处理 |
|
|
149
|
+
| `retryable_failure` | 未达上限时回到 pending 并退避 | 整批需要重试,且重试有意义 |
|
|
150
|
+
| `permanent_failure` | batch 内 delivery 进入 permanent_failed | 整批已确定无法成功 |
|
|
151
|
+
|
|
152
|
+
成功响应为 `applied`、`duplicate` 或 `stale`。`duplicate` 表示重复 ACK 已安全处理;`stale` 表示 ACK 已晚于当前持久状态,Push Server 不应尝试覆盖状态。
|
|
153
|
+
|
|
154
|
+
V1 无法表达批内混合结果。当前 Mock 策略为“存在永久失败则整批永久失败;否则存在临时失败则整批重试;否则 accepted”。生产接入必须明确并测试自己的批次策略;需要逐项结果时应升级协议,而不是私自扩展 V1 请求。
|
|
155
|
+
|
|
156
|
+
### 4.5 Push Service 侧最小配置
|
|
157
|
+
|
|
158
|
+
| 配置 | 用途 |
|
|
159
|
+
| --- | --- |
|
|
160
|
+
| `AUN_PUSH_ENABLED` | 启用 Push Service 业务处理 |
|
|
161
|
+
| `AUN_MESSAGE_OFFLINE_PUSH_ENABLED` | 允许 Message 产生离线候选 |
|
|
162
|
+
| `AUN_GROUP_OFFLINE_PUSH_ENABLED` | 允许 Group 产生离线候选 |
|
|
163
|
+
| `AUN_PUSH_ALLOWED_SERVER_AIDS` | 允许登记和接收批次的同域 Push Server AID |
|
|
164
|
+
| `AUN_PUSH_TOKEN_MODE` | 当前隔离 PoC 只能设 `plaintext`;生产禁止 |
|
|
165
|
+
|
|
166
|
+
频控、batch、ACK timeout、registration TTL 和诊断配置见运维指南。Push Server 不应依赖这些内部值来判断消息是否存在。
|
|
167
|
+
|
|
168
|
+
## 5. 使用 Mock Push Server 演示
|
|
169
|
+
|
|
170
|
+
### 5.1 演示能力和数据边界
|
|
171
|
+
|
|
172
|
+
Mock 使用当前 Python SDK 建立真实 AUN 长连接,并提供 token 签发、通知记录、故障注入和断连控制。平台推送被持久化 receipt 代替,不会真的调用 APNs、FCM 或 WebPush。
|
|
173
|
+
|
|
174
|
+
演示只允许复用既有只读身份:
|
|
175
|
+
|
|
176
|
+
| 环境变量 | 说明 |
|
|
177
|
+
| --- | --- |
|
|
178
|
+
| `AUN_MOCK_PUSH_AID` | 已存在的同域 Push Server AID |
|
|
179
|
+
| `AUN_MOCK_PUSH_IDENTITY_ROOT` | 含 `public/` 和 `private/` 的身份根,Compose 只读挂载 |
|
|
180
|
+
| `AUN_MOCK_PUSH_HMAC_SECRET` | Mock token HMAC secret,至少 24 字节 |
|
|
181
|
+
| `AUN_MOCK_PUSH_CONTROL_TOKEN` | Mock 控制面 Bearer token,至少 16 字节 |
|
|
182
|
+
| `AUN_MOCK_PUSH_DATA_ROOT` | 独立 Mock 状态目录,不得与 AID 目录重叠 |
|
|
183
|
+
| `AUN_MOCK_PUSH_PORT` | 宿主机控制端口,默认 `18991` |
|
|
184
|
+
|
|
185
|
+
Mock 的 PEM 身份路径不需要 seed。使用 SDK `key.json` 身份时,seed 只能通过构造参数或 `AUN_SEED_PASSWORD` 显式传入;运行时不读取 `.seed` 文件。
|
|
186
|
+
|
|
187
|
+
### 5.2 启动隔离环境
|
|
188
|
+
|
|
189
|
+
在已选择并核验 `agentid.pub` 单实例材料后,叠加 Push PoC Compose:
|
|
190
|
+
|
|
191
|
+
```powershell
|
|
192
|
+
docker compose --env-file agentid.pub/local.env --project-directory . `
|
|
193
|
+
-f docker-compose.yml -f agentid.pub/docker-compose.yml `
|
|
194
|
+
-f docker-compose.push-poc.yml --profile push-poc up -d
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
该命令会启用明文 token 和 Message/Group 候选,仅限隔离环境。执行前仍需按《aun测试运行指南》取得启动授权、重建包含当前源码的镜像,并核对 Compose project、数据根和固定身份挂载;不得加 `-v`,不得重建身份或清库。
|
|
198
|
+
|
|
199
|
+
Mock 就绪后,未认证健康检查应返回 `{"status":"ok"}`:
|
|
200
|
+
|
|
201
|
+
```powershell
|
|
202
|
+
Invoke-RestMethod http://127.0.0.1:18991/health
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### 5.3 签发演示 token
|
|
206
|
+
|
|
207
|
+
除 `/health` 外,Mock 控制 API 都要求 `Authorization: Bearer`:
|
|
208
|
+
|
|
209
|
+
```powershell
|
|
210
|
+
$headers = @{Authorization="Bearer $env:AUN_MOCK_PUSH_CONTROL_TOKEN"}
|
|
211
|
+
$body = @{target_aid=$aid; device_id=$device; slot_id=$slot; ttl_seconds=3600}
|
|
212
|
+
$issued = Invoke-RestMethod http://127.0.0.1:18991/v1/tokens `
|
|
213
|
+
-Method Post -Headers $headers -ContentType application/json `
|
|
214
|
+
-Body ($body | ConvertTo-Json)
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
将 `$issued.push_token` 交给目标客户端的 `connect()`。请求中的 AID、device 和 slot 必须与客户端当前安装完全一致。
|
|
218
|
+
|
|
219
|
+
### 5.4 完成一次 smoke
|
|
220
|
+
|
|
221
|
+
1. 目标客户端使用签发的 token 建连,确认 `connect()` 无错误返回。
|
|
222
|
+
2. 关闭目标 AID 的所有长连接,确保其通过在线宽限期和聚合窗口。
|
|
223
|
+
3. 由另一个 AID 发送可靠 P2P 或 Group 消息。
|
|
224
|
+
4. 查询 Mock receipt,确认出现相应 `delivery_id`,且通知记录不包含消息正文或原始 token。
|
|
225
|
+
5. 重新连接目标客户端,通过原有同步/pull 得到真实消息。
|
|
226
|
+
|
|
227
|
+
```powershell
|
|
228
|
+
Invoke-RestMethod "http://127.0.0.1:18991/v1/notifications?limit=100" `
|
|
229
|
+
-Headers $headers
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
仓库中的可执行 smoke 入口为:
|
|
233
|
+
|
|
234
|
+
```powershell
|
|
235
|
+
python tests/integration_test_push_service_poc.py --scenario smoke
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
脚本还支持 P2P、多设备、登记更新、注销、聚合、频控、batch 拆分、ACK timeout/dedup、迟到 ACK、无效 token 重登记和迁移恢复。运行身份、Mock URL、状态根等环境变量以脚本开头的强制校验为准;完整环境纪律见《aun测试运行指南》。
|
|
239
|
+
|
|
240
|
+
### 5.5 故障演示
|
|
241
|
+
|
|
242
|
+
Mock 的 `PUT /v1/faults` 支持 ACK 延迟、丢 ACK、ACK 前断连、临时失败、永久失败和无效 token。以下示例模拟丢 ACK:
|
|
243
|
+
|
|
244
|
+
```powershell
|
|
245
|
+
$fault = @{drop_ack=$true} | ConvertTo-Json
|
|
246
|
+
Invoke-RestMethod http://127.0.0.1:18991/v1/faults `
|
|
247
|
+
-Method Put -Headers $headers -ContentType application/json -Body $fault
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
观察同一 `delivery_id` 被重试但只产生一次 notification receipt;完成后用空对象 `{}` 重置故障。`POST /v1/events/replay` 可验证重复事件幂等,`POST /v1/disconnect` 可验证长连接恢复。
|
|
251
|
+
|
|
252
|
+
## 6. 接入验收清单
|
|
253
|
+
|
|
254
|
+
- connect 登记成功;同一安装重新登记时 version 递增,注销重复调用仍成功。
|
|
255
|
+
- 目标 AID 有长连接时不产生离线通知;全部长连接离线后才产生。
|
|
256
|
+
- Push Server 收到的事件只有唤醒元数据和 opaque token,没有正文、密文或发送者隐私数据。
|
|
257
|
+
- 重复 `delivery_id` 不重复调用平台,ACK 丢失或 timeout 后能够安全重试。
|
|
258
|
+
- token 轮换后旧 registration version 不会继续产生新 delivery;token 身份不匹配会被拒绝。
|
|
259
|
+
- 平台唤醒后,客户端能通过原有 AUN pull 获得并 ACK 真实消息。
|
|
260
|
+
- 日志、诊断、Mock SQLite 和错误响应中均没有原始 token、平台凭据、seed 或私钥。隔离 PoC 的 Push Service 数据库仍以明文保存 token,必须限制访问;生产必须先完成可信加密。
|
|
261
|
+
|
|
262
|
+
## 7. 常见问题
|
|
263
|
+
|
|
264
|
+
| 现象 | 首要检查 |
|
|
265
|
+
| --- | --- |
|
|
266
|
+
| `connect()` 因登记失败整体失败 | Push Server AID 是否同域且在 allowlist;token 是否非空且未超长度;Push Service/Gateway 是否就绪 |
|
|
267
|
+
| 目标离线但没有事件 | 是否仍有该 AID 的长连接;registration 是否启用;Message/Group 候选开关是否开启;在线查询是否处于 unknown |
|
|
268
|
+
| Push Server 收不到批次 | 是否使用长连接;AID 是否与 batch owner 一致;最早长连接是否属于另一个实例 |
|
|
269
|
+
| 平台通知重复 | ACK timeout 和结果未知会重发;必须检查 `delivery_id` 持久幂等,而不是按 `batch_id` 去重平台副作用 |
|
|
270
|
+
| ACK 返回 `stale` | ACK 已迟到或 batch 已被恢复流程处理;记录结果并停止覆盖,不是重新写状态的理由 |
|
|
271
|
+
| Mock 控制 API 返回 401 | Bearer control token 缺失或不一致;`/health` 是唯一免认证入口 |
|
|
272
|
+
| 生产环境拒绝启动 | 当前 plaintext token mode 被安全门主动阻断,不能通过降级配置绕过 |
|
|
273
|
+
|
|
274
|
+
## 8. 生产接入前的硬门
|
|
275
|
+
|
|
276
|
+
在真实 APNs、FCM 或 WebPush 上线前,至少完成:token 可信加密与密钥管理、Push Server 持久幂等库、平台凭据安全存储、控制面鉴权与限流、批次混合结果策略、容量与公平性测试、ACK/断连/重启恢复、敏感信息扫描和灰度回滚演练。
|
|
277
|
+
|
|
278
|
+
未完成 token 加密时只能运行隔离 PoC,不存在生产灰度路径。
|
|
279
|
+
|
|
280
|
+
## 9. 权威入口与代码索引
|
|
281
|
+
|
|
282
|
+
- 对外协议:[`protocol/15-离线推送通知协议.md`](protocol/15-离线推送通知协议.md)
|
|
283
|
+
- Python 客户端:[`sdk/04-连接与认证.md`](sdk/04-连接与认证.md)、[`sdk/06-API手册.md`](sdk/06-API手册.md)
|
|
284
|
+
- Push facade:`python/src/aun_core/facades.py`
|
|
285
|
+
- Mock Push Server:`python/src/aun_core/testing/mock_push_server.py`
|
|
286
|
+
- 可执行 PoC:`python/tests/integration_test_push_service_poc.py`
|
|
287
|
+
- Compose 叠加层:`../docker-deploy/docker-compose.push-poc.yml`
|
|
288
|
+
- 运维发布:[`AUN离线推送服务运维与发布指南.md`](AUN离线推送服务运维与发布指南.md)
|
|
289
|
+
|
|
290
|
+
若本文与代码或冻结契约冲突,以 `docs/superpowers/契约冻结-v3-to-v4.md` 和当前代码为准。
|