MATRIX X · PRIVATE COMMUNICATION INFRASTRUCTURE · 基础工程 16 / 16 · 全局迁移工程 15 / 15

隐私,不是一个开关。
是下一代通信底座。

让服务器可靠运送消息,但不再长期保存聊天历史。E2EE 进一步让服务器连投递中的正文也无法读取;两条边界不能混成一个开关。

当前真实进度:Private Chat 基础与全局本地优先迁移工程均已收口,L01–L15 为 15 / 15。真人 TestFlight、10 天观察、S3 生命周期和分阶段灰度已延期;当前尚未上线 E2EE,生产密文运行时与用户入口仍关闭,资源和旧历史物理删除均未开始。

16 / 16 Private Chat 基础15 / 15 全局迁移工程0 剩余工程刀0 生产删除授权
PRIVATE CHANNELENGINEERED · NOT YET OPEN
A发送设备明文 + 私钥
BLIND RELAY只见密文授权 · 路由 · 投递
B接收设备私钥 + 明文
设备 A每台设备一份独立密文设备 B
CLIENT HOLDS KEYSSERVER ROUTES CIPHERTEXTS3 STORES CIPHERTEXTFAIL CLOSED

THE INVESTMENT CASE

把隐私能力,
变成产品护城河。

我们不是为一张“已加密”徽章投入,而是在已有 IM 上建立一条可审计、可扩展、可随时停止的信任基础设施。

01产品护城河

把信任写进基础设施

私密通信不是一枚营销标签,而是账号、设备、消息与媒体共同遵守的系统边界。它让安全承诺可以被验证,而不是被相信。

02架构复用

不重造 IM,只重画信任边界

保留现有登录、聊天、推送和 S3 资源底座;客户端掌握密钥,服务端收缩为授权、盲路由与可靠投递。

03可控投入

代码完成不冒充产品上线

工程能力已经收口。当前没有真实用户,真人试点、十天观察、生命周期和分阶段灰度延期;观测与停止能力继续保留。

核心判断
真正的差异化,不是服务器承诺不看;
而是架构让它根本看不了。

ARCHITECTURE · ONE SCREEN

一张图看懂:
谁拥有明文,谁永远不能拥有。

服务器没有消失。它仍负责授权、限流、排队、重试与可靠投递,只是被明确排除在解密边界之外。

TRUSTED · DEVICE A
MX

发送方 iOS

  • 生成与保存私钥
  • 加密消息与媒体
  • 逐设备生成 envelope
SERVER-BLIND CONTROL PLANE

看得见投递,看不见内容

AUTH设备授权 / 撤销IM-CORE预密钥 / 盲信箱PUSH通用消息唤醒S3密文媒体对象

可见:公开密钥、设备 ID、必要路由元数据
不可见:正文、私钥、会话状态、媒体 key

TRUSTED · DEVICE B
MX

接收方 iOS

  • 验签与解密
  • 原子推进 ratchet
  • 本地安全落盘
TRUST CONTRACT

端上拥有内容服务端拥有可靠性但没有解密能力

HOW A MESSAGE MOVES

一条消息,六个不可跳过的安全动作。

每一步都保留恢复能力,但没有任何一步允许服务端拿到正文。

  1. 01

    确认设备

    读取已授权设备与签名预密钥,不向服务端索取私钥。

  2. 02

    本地建链

    在发送设备内建立独立会话,为每台目标设备生成不同密文。

  3. 03

    密文入队

    盲信箱只保存 envelope、TTL 与最小投递元数据。

  4. 04

    通用唤醒

    Push 只说“有新消息”,不携带正文、预览或媒体地址。

  5. 05

    设备解密

    接收设备验签、解密并原子推进 ratchet,失败绝不回退明文。

  6. 06

    落盘后确认

    消息和状态安全落盘后才 ACK;重试不会制造第二条消息。

L09 · DEVICE-TO-DEVICE HISTORY MIGRATION

历史不在云端。
换设备也不丢失。

Matrix X 不把聊天数据库变成永久云备份。旧设备直接把本地唯一历史加密交给新设备;服务端只做 24 小时盲中转,既看不到内容,也拿不到迁移密钥。

SOURCE · TRUSTED
12,480本地消息

旧设备

生成一致性快照、分片加密和 Manifest;原历史不会因迁移自动删除。

密文分片→≤ 4 MiB / chunk
BLIND TRANSFER PLANE

S3 · 24h

服务器密钥
0
EC2 资源字节
0
生产会话
0

im-core 仅保存会话、分片状态和密文摘要;运行开关保持关闭。

校验后下载→resume + verify
TARGET · TRUSTED
100%原子导入

新设备

只补缺失分片;全部通过摘要与认证标签后,才一次性提交本地数据库。

  1. 01

    新设备出示一次性二维码

    二维码只携带迁移声明和 32 字节端到端迁移秘密;服务端拿不到秘密,也不能替设备批准。

  2. 02

    旧设备核对并授权

    来源设备显示目标设备、账号和有效期,用户确认后才建立迁移会话;撤销设备不能继续上传或下载。

  3. 03

    本地导出并分片加密

    本机数据库生成稳定快照,按不超过 2 MiB 明文分片独立加密,并把顺序、摘要与 Merkle 根绑定进 Manifest。

  4. 04

    S3 盲中转 24 小时

    设备凭预签名票据直接上传密文;im-core 只保存状态和密文索引,EC2 不持久化资源字节。

  5. 05

    断点续传与完整性复核

    新设备仅补缺失分片;任一长度、摘要、认证标签或根摘要不一致,整批拒绝,不导入半份历史。

  6. 06

    原子导入后回执删除

    全部验证通过才一次性切换本地历史;ACK 后回收中转对象,来源设备原历史保留,直到用户自行处理。

L09 工程已验收,能力仍处于暗部署iOS 与 im-core 已合并 main · 生产开关 false · 试点账号 0 · 中转表 0 行 · 路由 404 · 不删除来源设备历史

L11 · LEGACY HISTORY RETIREMENT

服务器旧历史,
不是说删就删。

先让设备证明自己拥有完整、可恢复的本地副本,再从真实 ACK 开始观察至少 90 天。当前线上只有证明能力,没有迁移流量,更没有删除接口。

CLIENT · DURABLE FIRST
200每页上限

设备本地归档

独立 SQLite 与冷存储先成功落盘,再推进检查点;不会把旧历史灌进热列表。

稳定分页→resume cursor
EXACT PROOF CONTROL PLANE

SHA-256

跨端摘要
1
观察期
90d
删除条数
0

im-core 只核对稳定清单、精确回执与观察状态;数据库约束锁死删除事实。

完整 ACK→no delete grant
AUDIT · FAIL CLOSED
0 / 0回执 / 证据

生产零迁移

能力关闭、试点账号 0、四条路由 404;90 天计时尚未开始。

  1. 01

    冻结旧历史清单

    im-core 为账号生成稳定边界、数量与摘要;迁移期间的新消息不混入旧快照。

  2. 02

    每页最多 200 条

    iOS 后台有界读取,避免一次装入全部历史,更不会逐条刷新当前聊天列表。

  3. 03

    先落本地再记断点

    消息先进入独立 SQLite 与冷存储;只有持久化成功后才推进受文件保护的检查点。

  4. 04

    跨端精确证明

    Swift 与 Go 对同一规范化清单计算 SHA-256;数量、边界或任一内容不一致都拒绝 ACK。

  5. 05

    ACK 启动 90 天观察

    观察期从真实完整回执开始,不能从代码合并或暗部署日期倒推。

  6. 06

    删除另行授权

    当前控制面只生成待回收证据,没有删除接口;生产删除事实始终为 false、false、0。

L11 工程已验收并暗部署,删除仍为零iOS PR #158 · im-core PR #231 · EC2 a17d5e5b9383 · enabled false · pilot 0 · routes 404 · rows 0/0 · delete false/false/0

ENGINEERING CLOSEOUT · RUNTIME DEFERRED

工程已经收口,
运行门按需恢复。

DARK DEPLOYED · DEFAULT CLOSED工程 15 / 15,生产仍关闭

EC2 已运行统一门禁与观测合同,当前仍是 phase=disabled、ready=false。真人验收、十天观察、生命周期和灰度延期,不再占用工程刀数。

01现在

工程收尾

15 / 15

L01–L15 代码、交互、协议、媒体、停止与回滚已经进入主线。

02门禁

真人验证

延期

TestFlight 双账号和双物理设备以后按真实用户窗口恢复。

03门禁

分阶段灰度

延期

当前无真实用户,不维护 2 人到 20 人的阶段账本。

04门禁

资源生命周期

延期

S3 生命周期不执行,物理删除继续关闭。

PRODUCTION CAPABILITY LOCKS5 / 5 关闭

Private Chatfalse

普通消息本地优先false

设备历史迁移false

资源物理删除false

旧历史删除false

生产变更授权false
LOW-CARDINALITY SIGNALS9 类固定信号

门禁判定gate_evaluated

会话打开conversation_opened

发送成功message_send_succeeded

发送失败message_send_failed

接收成功message_receive_succeeded

接收失败message_receive_failed

迁移成功history_migration_succeeded

迁移失败history_migration_failed

停止触发stop_triggered

只记录阶段、结果与错误分类;账号、设备、会话、消息、正文、Token 与密钥一律不进入信号。
STOP ACTIONstop_and_rollback

出现明文 canary、解密完整性失败、跨账号数据、迁移损坏、不可恢复崩溃或门禁事实不一致时,立即停止并回滚;不得以“继续观察”掩盖安全异常。

线上构建99c0d6f761bf
控制合同matrixx.local-first-pilot/v1
信号合同matrixx.local-first-pilot-signal/v1
隐私事实identity=false · content=false

iOS PR #164im-core PR #237Knowledge 494

L13 · GROUP E2EE PROTOCOL POC

一个群,一份密文。
成员变化,整群换纪元。

PROTOCOL POC PASSED · PRODUCT CLOSEDm.megolm.v1.aes-sha2

发送方每个安全纪元只加密一次;成员变化先冻结发送、轮换纪元,再允许新密文进入盲中继。

matrix-sdk-crypto-ffi 0.17.0
OLM FAN-OUT群聊拒绝

逐设备 Olm 扇出

群规模增长时,每条消息都要为每台设备生成密文,成本和失败面随设备数线性增长。

MEGOLM V1L14 候选

Matrix 群组会话

与现有官方 Matrix Crypto FFI 同源;三设备、两纪元、乱序、篡改、退群隔离已在隔离 POC 通过。

MLS · RFC 9420延期,不否决

Messaging Layer Security

后妥协安全更强,但当前没有完成审查的 shipping Swift / FFI 接线;留作协议升级路径。

AAlice管理员 · 本地会话
BBob成员 · epoch 1 后移除
CCharlie成员 · epoch 2 可解密
SERVER-BLIND RELAY正文命中 0只见 room · epoch · roster digest · ciphertext
  1. 01
    PREPARE

    校验操作者权限、二级确认、协议支持和唯一可信设备名单。

  2. 02
    DRAIN

    Outbox 与媒体任务必须排空;任何未完成投递都阻止切换。

  3. 03
    EPOCH 1

    首个群组会话激活;服务端只协调公开 epoch 与 roster 摘要。

  4. 04
    ROTATE

    加人、退群、设备变化或周期阈值触发冻结,并且只允许精确 +1。

  5. 05
    EPOCH 2

    新纪元恢复发送;已移除成员不能解密之后的消息。

3独立设备

Alice、Bob、Charlie 分别持有本地密码状态

2安全纪元

成员变化后完成精确 +1 切换

56 / 56协议包测试

乱序、篡改、重放和退群隔离全部通过

0中继正文命中

密文与公开协调状态未命中明文 canary

KNOWN LIMITATIONS

选择可交付路线,不包装成算法胜利。

  • Megolm 不是“比 MLS 更安全”;本期选择基于当前代码、官方引擎和一人团队的可交付性。
  • L13 只证明协议与公开协调状态机可行,不包含群聊 UI、密钥分发、生产路由或数据库接线。
  • 成员变化期间必须冻结发送;旧纪元密文不能伪装成新纪元继续投递。
PRODUCT & PRODUCTION LOCKS5 / 5 关闭

群聊产品入口false

运行路由0

数据库迁移0

生产 E2EE 群0

正式进度推进false

iOS main0d42acfcb5fd
im-core main27babaaf0e96
Knowledge5b008e6fa7ad
工程进度15 / 15 · 已收尾

iOS PR #165im-core PR #238中文验收 495

L14 · PRODUCT MESSAGE ROUTING

一条消息,只有一条权威道路。

客户端不再自己猜“这个群是不是加密”。每次进入消息链路,都先读取服务端认证后的安全状态;一旦受保护,旧明文道路永久失效。

01STANDARD

普通群

standard

继续使用普通本地优先链路;不会因客户端猜测而升级。

02PROTECTED

加密群 · active

encrypted

只允许 Megolm 密文;正文、受保护历史和待发事实留在设备本地。

03PAUSED

准备或轮换中

blocked

冻结发送,等待新 epoch 与设备名单完成;绝不临时回退旧明文接口。

TRUSTED DEVICE本地明文与历史K12 local pending · local_only
AUTHORITATIVE ROUTEmatrixx.group-e2ee/message-route/v1认证成员 · 防进程内降级 · 15s cache
MEGOLM设备端生成密文文字 / 回复 / @ / 静默意图 · 媒体 fail closed
IM-CORE BLIND RELAY只路由 ciphertext旧 /im/message/send 已围栏
iOS main54d1e0459fa9
im-core main314b4b048880
iOS 回归135 pass · 0 fail
工程进度15 / 15 · 已收尾

iOS PR #193 · 013def7ab7c2im-core PR #247 · 明文围栏im-core PR #248 · 权威路由中文验收 496

L14 · ENCRYPTED PRODUCT CONTENT

真实聊天语义,
也不能泄露给服务器。

回复关系、@ 对象和静默意图不是“顺手加几个服务端字段”。它们先在设备端组成稳定负载,再整体进入群密文;im-core 继续只看见不透明信封。

TEXTREADY

文字

正文进入版本化应用负载,再交给 Megolm;旧版未包裹文字仍可投影。

REPLYREADY

回复

回复标识与当前正文一同加密,本地历史解密后恢复引用关系。

MENTIONREADY

@ 提及

目标、角色与显示名在端侧校验;重复、冲突或正文无令牌时拒绝发送。

SILENTPARTIAL

静默意图

is_silent 已进入密文;通知消费端尚未接线,不能宣称静默行为完成。

COMPOSER校验当前可见语义64 KiB 上限 · 未知类型拒绝
CANONICAL PAYLOAD四字段稳定编码message_type · content · at_users · is_silent
MEGOLM + BLIND RELAY服务器只路由密文后端变更 0 · 新部署 0
LOCAL HISTORY解密后唯一投影SQLite 明文 canary 0
iOS main9767b4c51947PR #199 · 8 / 8
定向回归19 / 19收紧提及后 5 / 5
架构 / 治理117 / 117治理 269 · UI 改动 0
独立动作生产 shipping 尚未开启runtime false · 真人与观察延期 · 删除关闭
加密意图 ≠ 产品行为完成

is_silent 已受保护,但 Notification Service Extension / 本地通知策略尚未消费;五类密文媒体已在总闸之后暗接线,不等于普通消息闭环或用户入口已开放。

L14 · ENCRYPTED MEDIA RESILIENCE

弱网中断,
不必从零开始。

图片、GIF、语音、视频和文件先在设备端成为密文。下载中断后,客户端只信任已经复核的完整密文分块;服务器无需新增资源字节副本、数据库长任务或解密能力。

01绑定公开合同

任务目录只使用不可逆摘要;checkpoint 不保存 token、票据、签名 URL、资源原值或媒体密钥。

02复核本机前缀

恢复前核对描述符、文件长度、完整分块边界与已提交密文前缀 SHA-256;不一致时在发起网络请求前失败。

03从完整块继续

每个 Range 完整同步落盘后才推进 checkpoint;网络中断只重取剩余密文字节,不重复下载已验证分块。

04短票据按需续签

401/403 最多重新申请两次下载票据,签名 URL 永不落盘,S3 请求也不携带 App Authorization。

05完整摘要再解密

全部分块完成后仍复核完整密文 SHA-256,再执行逐块认证和解密;断点不能替代最终完整性。

真实媒体角色5 / 5图片 · GIF · 语音 · 视频 · 文件
共享 SDK36 / 36PR #4 · 必需状态 2 / 2
iOS 主线8 / 8架构 117 / 117 · 治理 284 / 284
短票据续签2 次仅 401 / 403 · 凭证不落盘
完成边界任务恢复 + 字节恢复 + 最终完整性

完整密文 SHA-256 仍是最终权威;网络瞬时失败保留断点,404/410、合同错误、摘要错误、解密错误和成功完成都会清理暂存目录。

后续增强杀进程后整对象自动串行 + Complete / 消息提交

本期已完成当前密文分块的系统后台承接与主动控制;整对象无人值守串行属于后续体验增强。production E2EE=false · S3 lifecycle applied=false

L14 · AUTHORITATIVE SECURITY CONTEXT

成员或设备一变,旧纪元立刻失去发送资格。

通知不可信、缓存不裁决、服务端不持钥。客户端强制回读版本化安全上下文;只有服务端能从已提交 roster 与实时可信设备目录中证明一个精确原因,端侧才启动既有换钥协调器。

01

事件只唤醒

Realtime / APNS 不携带安全结论,只通知客户端重新读取。

02

清除旧判断

当前群路由缓存立即失效,避免 15 秒窗口继续使用旧 roster。

03

权威双读

im-core 读取状态 A、实时 roster、状态 B;摘要变化直接冲突。

04

精确判因

只接受成员加入、成员移除、设备新增或设备撤销;混合变化失败关闭。

05

稳定事件

epoch、前后 roster 摘要和原因共同生成 change_id,重复唤醒不会重复轮换。

06

端侧换钥

iOS 再次校验后调用既有协调器:精确 key-share、提交新 epoch、恢复密文发送。

member_addedTRUSTED

成员加入

账号集合只增加

新成员只进入新 epoch,不能读取服务器不存在的旧明文。

member_removedTRUSTED

成员移除

账号集合只减少

旧 epoch 立即冻结,被移除成员拿不到之后的新 key。

device_addedTRUSTED

可信设备新增

成员不变、设备增加

新设备从新 epoch 开始;旧历史只能由可信设备端到端迁移。

device_revokedTRUSTED

可信设备撤销

成员不变、设备减少

撤销设备被排除在下一轮 key-share 之外。

AMBIGUITY BOUNDARY混合变化、跨账号设备标识冲突或目录故障:暂停发送,不猜原因。

通知只能叫醒客户端,不能命令轮换;稳定 change_id 绑定群、epoch、前后 roster 摘要与原因,同一变化被多路重复唤醒时只执行一次。

后端精确分类PR 2 / 2 · main 2 / 28b78656edf73
iOS 自动唤醒29 / 29 · 架构 117 / 1173092e28a0e76
可信原因4 / 4 白名单stable change_id · true
生产事实暗部署 · 三路 4048b78656edf73

L14 · DURABLE PERIODIC ROTATION

密钥不会永久有效。
时间与消息量,谁先到谁换钥。

每台设备各自计数必然分叉。Matrix X 让 im-core 只保存公开 epoch 窗口,让端侧继续独占真正密钥:服务端裁决“旧 key 还能不能用”,设备完成新 key 的生成、分发与本地保存。

TIME24HOURS
EPOCH01→02DEVICE-GENERATED KEY
MESSAGES100ACCEPTED

PUBLIC WINDOW ONLY · SERVER KEY COUNT 0 · PLAINTEXT COUNT 0

  1. 01
    建立窗口

    新 epoch 提交时原子写入 count=0 与 24 小时截止时间。

  2. 02
    只数已接收

    每个新幂等键成功接收一次才加一;网络重试回放原回执。

  3. 03
    第 100 条成功

    消息先完成服务端接收与本地耐久提交,再标记必须换钥。

  4. 04
    后台换钥

    端侧生成新 sender key,精确分发给当前可信设备并提交新 epoch。

  5. 05
    第 101 条封锁

    若后台换钥失败,专用 423 阻止旧 epoch 继续发送,绝不回退明文。

  6. 06
    同一消息恢复

    只丢弃未接收 prepared 密文;以同一 messageID 在新 epoch 下重封装。

多设备并发群级事务锁 + 窗口行锁

只会有一条成为第 100 条

进程重启窗口写入 PostgreSQL

计数与截止时间不会归零

网络重试幂等回执保存 count / deadline

同一请求不会重复计数

客户端恢复prepared 与 serverAccepted 分离

成功消息不会被误删重发

当前裁决双端主干全绿 · 后端默认关闭暗部署 · 用户入口关闭

iOS 与 im-core 已合并 main;后端五角色精确,周期窗口 0 行、发布阻断 0。工程验收已经计入 15 / 15,TestFlight 与真人运行验证延期。

iOS 729667f00e9d · im-core / EC2 07974ea14207

im-core PR #252iOS PR #197中文事实 499

L14 · ONE COHORT, ONE SAFETY LOOP

只保留一套真人队列,
把群聊风险接回统一停止控制。

这不是再造一个运营后台。L14 必须与 L12 使用完全相同的 revision 和账号集合;任一漂移都在进程启动时失败关闭,公共 meta 不暴露账号主体。

01队列一致性

同 revision · 同账号集合

子集、超集、空 revision 和 L12 未就绪全部拒绝;不存在“群聊先给部分人偷偷打开”。

02匿名观测

4 类固定低基数信号

group_delivery · group_decrypt · group_epoch_transition · group_media

03自动化验收

52 / 53 通过

0 失败、1 条既有条件性跳过;架构门禁 117 / 117,iOS 必需状态 8 / 8。

04生产裁决

默认关闭 · 独立启用

configuration ready=false · runtime=false · shipping=false;真人 TF、10 天观察和分阶段灰度已延期。

依赖合同matrixx.local-first-pilot-dependent/v1im-core / EC2b020b29b3dceiOS mainad1bd6ed4189Knowledge maina1b99c2191bc

im-core PR #261iOS PR #226中文事实 516

生产收敛

代码已经收口。运行验证按需恢复。

“工程完成”“生产关闭”“运行延期”分开显示,不把延期冒充验收通过。

01四类可信成员/设备变化的自动换钥唤醒链

后端已对齐生产,iOS 已进主干

b900bf559956 · iOS #238–#241 · 生产关闭。

02资源链

代码已合并,生产等待授权

主干 64c7b7c05e60 · 生产 8d3a9c615af7 · AWS 替换 0 · 删除关闭。

延期项真人 TestFlight · 10 天观察 · S3 生命周期 · 分阶段灰度正式进度工程 15/15 · 运行验证延期试点 / 观察0 / 2 人 · 0 / 10 天物理删除未授权 · false · messageLoopLinked=false

中文事实 517 · 完整版本与 PR 证据

REALITY, NOT THEATRE

安全底座完成。
全局迁移工程 15 / 15。

旧 K01–K16 证明 Private Chat 的协议工程基础;L01–L11 完成本地优先、单聊密文、设备迁移、十二类资源治理和旧历史回收控制。L12 完成统一准入、观测、停止与回滚;L13 完成 Megolm POC;L14 将权威路由、换钥、文字语义、五类密文媒体、后台当前分块、主动控制、7/127/2500 群规模和双模拟器验收接入主线;L15 的群主/有权限管理员直接开启 UI 也已合并。真人 TestFlight、10 天观察、S3 生命周期与分阶段灰度延期。生产 shipping、密文运行时、迁移与删除继续关闭,是否全量开启另行决定。

L11 真实验收:iOS PR #158 · im-core PR #231 · EC2 a17d5e5b9383 · 200 条分页 · 90 天观察 · 路由 404 · 表 0/0 · 删除 false/false/0 · 中文验收 489

L12 控制面:iOS PR #164 · im-core PR #237 · EC2 99c0d6f761bf · Knowledge b7a03e85c59e · phase disabled · ready false · 账号 0 / 2 · 观察 0 / 10 天 · 中文事实 494

L13 并行 POC:iOS PR #165 · im-core PR #238 · m.megolm.v1.aes-sha2 · 三设备 · 两纪元 · 56 / 56 + 4 / 4 · 中继明文 0 · 产品入口 false · 生产群 0 · 中文验收 495

L14 文字产品路由:iOS PR #193 · im-core PR #248 · iOS 54d1e0459fa9 · im-core 314b4b048880 · plaintext fallback false · shipping false · 权威安全上下文后端已暗部署、iOS 已合并 · 中文验收 496

L14 可信换钥链:iOS PR #195 · im-core PR #251 · iOS 3092e28a0e76 · im-core / EC2 8b78656edf73 · 四类原因 · stable change_id · notification wake-only · shipping false · 中文验收 498

L14 周期换钥:iOS PR #197 · im-core PR #252 · 24 小时或 100 条 · 第 100 条成功 / 第 101 条 423 · iOS 729667f00e9d · im-core / EC2 07974ea14207 · 五角色 · 窗口 0 行 · 四路 404 · shipping false · 中文事实 499

L14 统一试点与观测:im-core PR #261 · iOS PR #226 · 后端 / EC2 b020b29b3dce · iOS ad1bd6ed4189 · Knowledge a1b99c2191bc · 同 revision / 同账号集合 · 四类匿名信号 · ready false · 账号 0 · 中文事实 516

L14 加密内容语义:iOS PR #199 · 文字 / 回复 / @ / 静默意图进入同一密文负载 · iOS 9767b4c51947 · 19 / 19 · 架构 117 / 117 · 服务端明文字段 0 · 静默通知消费作为后续增强,媒体由事实 507 接续 · 中文事实 500

L14 密文媒体恢复:共享 SDK PR #4 · iOS PR #207 · 五类媒体真实收发入口 · 无敏感值任务账本 · 64 KiB checkpoint · 完整分块续传 · 401/403 最多续票两次 · 最终密文 SHA-256 · SDK 36 / 36 · iOS 8 / 8 · 后续已完成当前分块后台收发和主动控制,整对象杀进程后自动串行仍延期 · 中文事实 507

K16 基础证据(历史):PR #186 · 51b009e · im-core · K16 试点白名单与路由修复 · PR #129 · 28250b7 · iOS · K16 试点判定器 · PR #131 · 2d4bb93 · iOS · 单一 Shipping 产品 · PR #133 · 4040f20 · iOS · Shipping 产品进入 App 编译图 · PR #134 · f7e513f · iOS · 发布输入中文路径恢复 · Run #82057 · 路径守卫通过 · 发布编排 · 精确源码输入 · PR #27 · 5ddda97 · 发布编排 · Runner 隔离身份合同修复 · PR #101 · 1c867f0 · Knowledge · 472 中文母版接线事实
历史四仓同构契约:1a8ce8b90ec8

ENGINEERING EVIDENCE · K03—K16

下面不是愿景。
是可以逐项复核的工程事实。

协议、设备身份、预密钥、会话门禁、盲信箱、iOS 状态机、密文媒体、多设备投递和试点门禁,全部保留到实现与证据层。

K03–K04 · PROTOCOL + STATE POC

协议能分发,还要真的扛住失败路径

K03 解决许可证与 iOS 分发,K04 用官方引擎验证 Olm 状态机。通过只代表允许设计设备身份,不代表产品入口或生产链已经可用。

当前裁决

K04 Olm 隔离 POC 通过 · 生产 No-Go

选中候选 matrix-sdk-crypto-ffi 0.17.0 · m.olm.v1.curve25519-aes-sha2 · Apache-2.0

自动证据
三设备状态机 PASS · iOS 16 arm64 编译 PASS
边界
K04 当时只放行 K05 设备身份设计;K16 已进入 App 编译图,但运行门禁和产品入口仍关闭
制品 SHA
7d5e15e072eccb8c
Private Chat 文本逐设备 Olm

每个目标设备独立 ratchet;已消费密文重放不返回正文。

Megolm一对一文本拒绝使用

群组房间会话需调用方另建 sender key / session / message index 重放账本;高层 FFI 不代管该账本

乱序投递PASS

Bob 两条消息逆序到达,均各解出一次

密文篡改PASS

不返回正文,不污染后续合法状态

完整重放PASS

已消费 Olm 密文不能再次得到明文

错误设备PASS

Bob 密文投给 Charlie 不返回正文

加密状态重开PASS

关闭并重开 store 后 ratchet 可继续

盲中继 canary0 命中

中继数据不含四段测试正文

候选许可证iOS / 维护事实结论
Signal libsignalAGPL-3.0第三方使用与消费方 SwiftPM 不受支持当前生产 No-Go
vodozemac 直连Apache-2.0无官方 Swift 消费包,需要自管 Rust FFIiOS 分发 No-Go
OpenMLSMITiOS 只构建不测试,且是 MLS 群组协议首版协议不匹配
Matrix Crypto FFIApache-2.0官方静态 XCFramework;Olm 三设备状态机与失败关闭已验证K04 隔离 POC 通过

iOS main 已完成单一 Shipping 产品和 App 编译接线;K04、K06–K16 的工程能力已经收口,但尚未启用 Private Chat 产品入口。 K09 后端运输面继续默认关闭;K14 已补齐 S3 密文资源,K15 已补齐新消息多设备。签名 TestFlight 与真人运行验证已经延期,不再阻塞工程收尾;生产是否开放是下一次独立产品决策。

K05 · CRYPTO DEVICE AUTHORITY

登录设备不等于密码学设备

K05 把账号主体、登录会话、登录/Push 设备和 Private Chat 密码学设备拆开。客户端持有私钥;Auth 只签发公共准入/撤销事件;im-core 只验证和投影。

01

账号主体

reits-auth 的稳定用户身份,不包含聊天私钥。

02

Auth 登录会话

可撤销的账号会话,只能申请一次性注册挑战。

03

登录 / Push 设备

服务普通登录与通知,不能直接充当 E2EE identity。

04

密码学设备

客户端生成 Ed25519 / Curve25519 私钥;公钥换代创建新 ID。

客户端本地生成私钥

私钥、Olm pickle、消息与媒体 key 永不上传。

reits-auth验证并签发

5 分钟挑战、候选设备签名、强认证/已有设备授权、完整请求幂等。

im-core只投影公共事件

Authority 签名失败关闭;revoked 设备立即退出未来投递集合。

本刀生产影响:0Private Chat v1 仍不可用 · 无 HTTP 路由 · 无数据库迁移 · 无运行时配置 · 无后端部署 · 无 iOS 产品入口 · 可用会话 0

K06 · PREKEY LIFECYCLE

离线首次建链,先把“一把钥匙只能领一次”做对

接收方不在线时,发送方只能领取公开 Prekey。K06 把设备准入、签名、过期、库存和并发语义冻结成 iOS / im-core 同一份机器契约。

signed prekey7 天最长有效期
库存上限100每台 active 设备
低水位20触发补充判断
补充目标100恢复完整库存
01
终端生成私钥只留本地

公开 publication 不含身份、signed/one-time 私钥,也不含正文或消息 key。

02
双分域签名整包 + signed prekey

Ed25519 分别签名,避免字段混签,signed prekey 可独立验真。

03
服务端校验只认 active K05 设备

publisher、requester、target 的 generation 必须和公共身份投影一致。

04
原子领取同 claim 重试不二次消费

同 ID 不同请求拒绝;空库存、过期、撤销、篡改全部失败关闭。

并发故障注入24 个请求竞争最后 1 把 key

1 次成功 · 23 次库存耗尽 · 0 次重复分配

contract sha256 · 1a8ce8b90ec8382938462489742484bf48184b3fdae28398a435453ef41562fe
K06 生产影响:0K06 当刀 App 接线 0;K16 现已完成编译接线 1/1 · 产品入口 0 · TestFlight 0 · 可用会话 0

K07 · PRIVATE_V1 CONTRACT

不是打开一个开关,而是五类事实同时成立

K07 先冻结独立会话和信封,再允许 K08 建表。普通聊天不能原地升级;远程 Feature Flag 只能表达服务端能力,不能替代客户端就绪度、双方白名单或证据新鲜度。

01
客户端协议支持

K12 隔离本地保护已通过,但 shipping App 仍固定 false;K16 试点硬化前不能放行。

02
服务端能力开启

private_chat_v1 只是一项服务端能力声明,默认 false。

03
发起账号白名单

真人批准的账号范围;缺失或撤回立即停止新建。

04
接收账号白名单

双方都必须获准,不能把未授权用户被动拉入试点。

05
门禁证据新鲜

能力与白名单 revision 必须存在且未过期。

CLIENT ∧ SERVER ∧ INITIATOR ∧ RECIPIENT ∧ FRESH全部为真才创建任一缺失 / false / 过期 → DENY · 不产生部分会话
独立会话

private_v1

协议
m.olm.v1.curve25519-aes-sha2
参与者
恰好 2 个账号
旧会话升级
DENY
并发重试
24 次只产生 1 条
纯密文信封

ciphertext-envelope/v1

密文上限
64 KiB
最长 TTL
14 天
签名
发送设备 Ed25519
未知字段
DENY
服务器禁止接收

明文不可表达

消息正文、消息 key、Olm pickle、身份/Prekey 私钥、媒体 key、Push 预览、可搜索消息内容。

未来生产事务SERIALIZABLE CONVERSATION CREATION
01

private_conversation

02

两条参与者记录

03

创建幂等记录

04

门禁快照摘要

05

无正文审计事件

K08 已修正跨网络单事务假设:先用 5 分钟 reservation 领取公开 OTK,客户端生成首密文后再以 SERIALIZABLE 事务提交会话、OTK、信箱和审计。
K07 生产影响:0正式 App 入口 0 · HTTP 路由 0 · 当刀数据库迁移 0 · 信封投递 0 · 后端部署 0 · TestFlight 0 · 可用会话 0 · K08 已完成存储内核

K08 · BLIND MAILBOX

服务器可以排队与确认,但数据模型不允许它读正文

K08 交付的是可审阅存储内核,不是已上线功能。12 张专用表只表达公开键、路由、密文、序号、TTL、ACK 和无正文审计。

专用表12只保存公开材料、密文与最小元数据
OTK reservation5 分钟过期后永久焚毁,不回流
最长 TTL14 天过期密文不再投递
单页上限100游标绑定设备和 generation
01
RESERVE

先交付公开 OTK

串行化领取一把 available OTK,相同 request 重试返回同一 reservation。一旦对外交付,这把键就绝不再分配给其他建链者。

02
COMMIT

再原子提交首密文

一个 SERIALIZABLE 事务同时写会话、参与者、幂等事件、OTK committed、设备序号、密文和无正文审计。

AVAILABLE→RESERVED→COMMITTED或ABANDONED · PERMANENTLY BURNED无任何路径回到 AVAILABLE;宁可浪费公开 OTK,也不允许键重用。
服务端负责

密文排队与设备隔离

按接收账号 + crypto device + generation 分区;序号单调;撤销设备不能 reserve、enqueue、pull 或 ACK。

iOS 负责

先耐久提交,后签名 ACK

乱序页先排序;全页新密文本地事务成功后才推进游标,产生 SHA-256 commit digest 和 Ed25519 ACK。

两端都不能退让

任何失败都不得回退明文

本地落盘失败不前移游标、不生成 ACK;跨设备 ACK、冲突重放、篡改和 generation 不一致全部拒绝。

K08 当刀生产影响:0K08 当时只交付存储内核;K09 才接入迁移角色和默认关闭运输面 · shipping App 入口 0 · 可用会话 0

K09 · CIPHERTEXT TRANSPORT

实时和 Push 只负责叫醒,盲信箱才是真相源

六条严格 HTTP 路由承载 reserve、commit、send、pull 和 ACK;WebSocket 只发 K07 密文信封;Push 只发两项通用唤醒字段。

严格 HTTP6 条账号绑定 · 192 KiB · 未知字段拒绝
WebSocket纯密文只传 private_envelope
Push 字段2 项schema_version + kind
运行时默认关闭路由不注册并返回 404
01
DURABLE FIRST

先写盲信箱

密文与单调序号进入 PostgreSQL 后才通知。任何实时或 Push 故障都不能撤销已经成立的消息事实。

02
CURSOR RECOVERY

断线统一补拉

重复帧忽略,序号缺口、重连和回到前台都触发 K08 不透明游标 pull;WebSocket 本身不推进耐久游标。

HTTP

身份与结构双重失败关闭

Bearer 账号必须等于业务主体;非 JSON、尾随 JSON、未知字段、跨账号 reserve/send/pull/ack 全部拒绝。

WebSocket

可以携带 envelope,不能携带正文

分角色部署通过 Redis Bus 转发密文帧;投递失败后按 HTTP cursor 恢复,不另造第二套消息真相。

Push 禁区

无标题、正文、身份和 URL

发送者、会话 ID、envelope、ciphertext、媒体 URL 任何一个出现都不符合 K09 契约。

K09 已发布,但默认关闭065 增量表结构可应用 · PRIVATE_CHAT_V1_TRANSPORT_ENABLED=false · 关闭时路由 404 · shipping App 入口 0 · TestFlight 0 · 可用会话 0 · K12 已完成隔离本地保护

K10 · IOS CRYPTO ADAPTER

业务只提交消息,密码状态只有一个主人

K10 不再让业务代码碰 OlmMachine、Curve25519 私钥或 Ratchet 状态。单一 Swift actor 负责公钥操作、逐设备密文、K07 签名信封、解密和重放防线。

官方协议引擎Olm 0.17.0不自研密码学原语
并发所有者1 actor串行推进密码状态
隔离测试5 / 5真实双端与故障注入
编译接线1 / 1K16 已链接,运行门禁关闭
OUT
DURABLE BEFORE COMMIT

先入盲信箱,再推进 Olm

Adapter 先返回 K07 签名密文;只有 K09 盲信箱明确耐久接受后,业务层才能提交出站密码状态。

IN
JOURNAL BEFORE PLAINTEXT

先落重放账本,再返回正文

验签、设备绑定和 Olm 解密通过后,先原子写入 envelope 摘要;写失败不返回正文并停止 Adapter。

业务可见

公开操作与受控结果

公钥目录请求、K07 密文信封、耐久后 commit、验证且落账后的私密文本。

秘密边界

句柄不可编码、不可导出

业务拿不到签名私钥、store 口令、Olm session 或 Ratchet;K12 已在隔离层补齐 Keychain 与文件保护装配。

K10 当时未完成

跨库恢复已由 K11 接续

K11 用仅密文 Outbox 和本机密钥加密恢复胶囊补齐崩溃窗口;这里保留 K10 的历史边界。

K10 历史边界已由 K11 闭环承接K10 当刀 App 接线 0;K16 现已完成编译接线 1/1 · 产品入口 0 · 私密会话 0 · TestFlight 0

K11 · TWO IOS TEXT LOOP

不是“能发一条”,而是任意一步被杀都能恢复

K11 将 K09 盲信箱、K10 Crypto Adapter 和独立 private_v1 本地事务拼成首个可执行双端闭环。Realtime 与 Push 只负责唤醒,权威事实始终来自 mailbox pull。

Swift Package27 / 27全部协议测试通过
K11 故障场景5 / 5离线、重启、篡改
服务端正文0im-core 只见密文
当刀接线0K11 当时保持隔离;K16 已完成编译接线
OUT
CIPHERTEXT OUTBOX FIRST

先本地耐久,再网络入队

消息与仅密文 Outbox 一起落盘;信箱接受后才推进 Olm。重启恢复同一密文,不重新加密或重复推进 Ratchet。

IN
ENCRYPTED RECOVERY CAPSULE

先保住可恢复正文,再提交 ACK

解密结果先封成本机密钥加密胶囊;本地消息提交后才推进 cursor 和签名 ACK。篡改时三者都不推进。

发送端故障

信箱接受后崩溃

重启幂等重试同一 envelope,服务端唯一信封仍为 1,本地 Outbox 最终清零。

接收端故障

三个写盘窗口全覆盖

恢复胶囊后、消息提交后、ACK 状态后分别杀进程,重启都只得到一条本地消息和一次 ACK。

历史边界

K11 不等于用户可用

K12 已补齐本地保护,K16 已完成编译接线;当前生产开关和产品入口仍关闭,因此不得宣称 E2EE 已上线。签名 TestFlight 与真人试点已延期。

K11 工程闭环完成,生产仍是 No-GoK11 当刀 shipping App 0;K16 现已完成编译接线 1/1 · 产品入口 0 · 私密会话 0 · 普通聊天不变

K12 · IOS LOCAL DATA PROTECTION

密文链安全,不代表设备落盘天然安全

K12 当刀把设备秘密、本地事务状态与搜索拆成三个失败关闭边界,并保持隔离;K16 已把它纳入 App 编译图,但没有开放产品入口,也不改变普通聊天。

Swift Package34 / 34全部协议测试通过
K12 定向测试7 / 7篡改、错身份、旧明文失败关闭
文件保护COMPLETE锁屏不可读
编译接线1 / 1运行入口 0,生产继续 No-Go
KEY
THIS DEVICE ONLY

秘密只从 Keychain 取句柄

设备材料使用 WhenUnlockedThisDeviceOnly;账号、设备与 generation 只形成哈希账户键,业务层拿不到原始秘密。

DATA
DOMAIN-SEPARATED AES-GCM

状态与身份绑定后再落盘

重放账本与 K11 状态使用不同 HKDF 域,AES-GCM AAD 绑定身份;篡改、错 key、错身份和旧明文全部拒绝。

本地搜索

认证后、只在内存中

用户在场认证签发短租约;搜索索引不进 SQLite、FTS、Spotlight 或日志,锁定立即清空。

最小暴露

诊断与通知不带正文

诊断只保留哈希标识和字节数;通知固定为“你有一条新私密消息”,不携带发送者、会话或内容。

产品边界

K12 不等于已经上线

K16 只完成 App 编译接线;产品入口、TestFlight 和真实私密会话仍为 0,密文媒体格式已由 K13 接续。

K12 本地保护完成,生产仍是 No-GoiOS PR #123 · Knowledge PR #95 · 普通聊天不变 · im-core/后端无改动 · 产品会话 0 · 已由 K13 接续

K13 · PRIVATE MEDIA WIRE FORMAT

先在设备端变成密文,再跨越资源服务边界

K13 交付的是可运行的项目中立格式,不是概念图:真实实现位于 im-media-send-kit,iOS 与 Knowledge 保存同一份机器合同。K14 才把公开描述符和密文对象接入 reits-media/S3。

K13 定向测试7 / 7格式、泄漏与失败路径
共享包全量26 / 26普通媒体能力无回归
对象 key独立主文件与缩略图不共用
生产接线0S3、App、TestFlight 均未接
STORE
SERVER-SAFE DESCRIPTOR

资源服务只看密文事实

只含不透明内容 ID、密文字节数、密文 SHA-256、块大小与块数;不含文件名、MIME、角色、明文摘要、key 或 nonce。

PEER
CONFIDENTIAL DESCRIPTOR

接收方材料不进入媒体服务

对象 key 与 nonce prefix 只放进已认证私聊消息;文件名、MIME、角色和明文完整性信息仍在独立认证密文内。

流式格式

AES-256-GCM 分块处理

默认 1 MiB 明文块,nonce 由对象随机前缀和块序组成;完整文件不进入内存,空文件也产生认证块。

失败关闭

任何异常都不提交明文

篡改、截断、附加、错 key、错对象、描述符冲突和元数据认证失败全部删除临时输出。

当刀边界

K13 当时只冻结媒体格式

K13 没有接入 reits-media 和 S3;该缺口已由 K14 资源闭环接续,K16 只完成编译接线,运行入口仍关闭。

K13 密文媒体格式完成,产品仍是 No-GoMedia PR #1 · iOS PR #124 · Knowledge PR #96 · 合同 SHA 60c92871db6b · K13 当刀 S3 0 · App 0 · 已由 K14 接续

K14 · PRIVATE MEDIA CIPHERTEXT V1

密文直达 S3,EC2 不落业务资源字节

K14 把 K13 的密文格式接到真实资源边界:reits-media 只签发上传与下载票据、核对密文大小和摘要;设备到 S3 直接传输,资源节点不做代理转发,也不保存临时文件。

共享 SDK 全量29 / 29K14 新增 3 条资源流测试
资源服务PASSGo test、vet、静态构建
资源节点落盘0ec2_persistent_asset_bytes=false
编译接线1 / 1入口、开关、TestFlight 均未开放
CONTROL
SERVER-SAFE DESCRIPTOR

资源服务只处理公开密文事实

不透明内容 ID、密文字节数、密文 SHA-256、分块参数和幂等键;文件名、MIME、媒体角色、明文摘要、key 与 nonce 一律拒绝。

DATA
SINGLE PUT / MULTIPART RESUME

设备与 S3 直接交换密文

小对象单次 PUT;大对象分片续传并跳过已完成分片。Bearer 令牌只发给媒体控制面,不随预签名请求进入 S3。

完整性

服务端流式复核密文 SHA-256

完成提交前从对象存储流式读取并核对长度与摘要;不把完整对象写到 EC2 临时目录。

下载

Range 密文回读

客户端按 K13 认证块范围请求,必须收到精确的 206 字节区间;任一摘要、长度或 tag 不一致都删除临时输出。

保留策略

逻辑删除

对象锁定期内只撤销业务可见性和后续下载票据,不承诺立即物理删除;生命周期继续由 S3 治理。

产品边界

K14 不等于产品已经开放

L14 已把五类密文媒体接到 shipping=false 后的真实收发入口,并补齐耐久任务账本、字节断点、短票据续签、当前分块后台传输与主动控制;用户入口仍关闭,整对象无人值守串行属于后续增强。

K14 资源能力完成,Private Chat v1 仍不可用reits-media PR #10–#12 · Media SDK PR #2 / #4 · iOS PR #126 / #207 · Knowledge PR #97 / 中文事实 507 · S3 只存密文 · EC2 资源字节 0 · shipping false · 产品入口 0

L10 ACCEPTED · UNIFIED RESOURCE LIFECYCLE

统一资源生命周期,不等于所有文件统一过期。

设备本地才是聊天资源的长期事实源;头像、MiniApp、业务文档、社交内容和构建产物各守自己的引用与合规周期。L10 已部署可回读合同,生产物理删除仍需独立授权。

统一资源分类12每类都有独立事实源与保留模式
现网可写资源类3MiniApp、业务资产、私密媒体密文
EC2 业务资源落盘0ec2_persistent_asset_bytes=false
生产删除授权0物理删除关闭 · GC disabled
资源类型长期事实源服务端保留到期体验
私密聊天原件private_chat_original设备本地S3 密文临时中转 30 天文件已过期,无法下载;可请对方重新发送或从完整设备迁移
普通聊天原件standard_chat_original设备本地S3 临时中转 30 天保留消息气泡与元数据,显示过期状态,不无限重试
聊天派生资源chat_derivative可由本地原件重建不得比原件活得更久优先重建;原件也不存在时展示过期
用户与群头像profile_and_group_avatar当前资料引用活动引用长期保留;失去引用后 30 天宽限回退默认头像并重试资料元数据
贴纸与表情包sticker_and_emoji_package已发布版本活动版本保留,至少留 2 个回滚版本显示占位并刷新资源包
动态与 Storymoment_and_story_media内容发布记录Story 24 小时;动态按产品删除与墓碑显示内容不可用,不冒充聊天重传
视频号与频道reel_and_channel_media已发布内容引用跟随内容生命周期,删除后再回收内容已移除或不可用
MiniApp 包miniapp_package不可变发布版本活动引用受保护;无引用版本才可清理回滚到可用版本或显示包不可用
业务资产business_asset业务记录引用按合规策略;必须有 Owner 与引用证据才能删除保留审计引用并显示业务记录不可用
设备迁移包migration_package来源设备本地数据库S3 密文中转 24 小时;导入成功立即删除要求来源设备重新发起迁移
链接预览缓存link_preview_and_external_cache外部源站与消息元数据有界缓存并定期重新验证文本链接仍保留,预览允许消失
日志与构建产物logs_and_build_artifacts可观测性或发布系统不进入 reits-media,使用独立留存与清理策略不是终端用户资源
聊天资源到期文件已过期,无法下载

消息文字、发送者、时间与资源类型仍留在本地时间线;不出现空白气泡,不无限转圈,也不静默延长服务器留存。

  1. 本机有原件继续离线打开,不受 S3 到期影响。
  2. 本机无原件可请对方重新发送。
  3. 另一设备完整从完整设备发起加密迁移。
L10 工程已验收并暗部署,删除能力继续失败关闭iOS #157 · send-kit #3 · media #13 · build 04fda241cd54 · 12 类策略 · S3 lifecycle false · 生产对象删除 0

K15 · AUTHORIZED DEVICE FAN-OUT

完整设备名单不是客户端猜出来的

K15 只解决未来新消息:发送端自己的其他设备与接收方全部活跃设备都拿到独立密文;服务端重新计算名单并用一个事务接收整批,不允许部分送达。

单账号上限5只认设备最高 generation
批次目标上限9排除当前发送设备
部分提交0任一失败整批回滚
历史迁移0继续作为独立项目
01
LATEST ACTIVE GENERATION

会话双方完整快照

名单摘要绑定会话、账号、设备 ID、generation 与签名公钥;最高代 revoked 时不能退回旧 active。

02
ONE DEVICE · ONE CIPHERTEXT

逐设备独立信封

接收方所有设备,加上发送端其他设备;每个目标拥有不同 ciphertext、envelope ID、幂等键与签名。

03
SERIALIZABLE FAN-OUT

名单变化就整批拒绝

im-core 重算摘要、验签全部信封、分配各设备序号;缺失、重复、撤销或写入失败时新增为 0。

发送端连续性

发送端其他设备

手机发送后,自己的平板也从独立 mailbox 收到新消息;服务器不能复制手机那份密文代替端侧加密。

提交前撤销

stale roster → 409

撤销使摘要变化,整批失败;仍活跃设备也不会提前看到半个批次。

提交后撤销

Pull 继续检查 active

已撤销设备不能领取尚未消费的信封;但不虚假承诺远程擦除它已经落盘的明文。

产品边界

K15 不等于产品已经开放

协调器已随 K16 Shipping 产品进入 App 编译图;运行入口、Feature Flag、TestFlight 和真实私聊会话仍为 0。

K15 多设备工程闭环完成,Private Chat v1 仍不可用im-core #183 已部署且门禁 false · iOS #127 隔离完成 · Knowledge #98 · K16 编译接线 1/1 · 产品入口 0 · 历史迁移 0

K16 · RUNTIME VALIDATION DEFERRED

工程已经完成,运行验证按需恢复

K16 工程代码已经合并 main,发布输入也通过 UTF-8 路径守卫。当前无真实用户,签名 TestFlight、生产白名单、真人体验和观察日统一延期;延期不等于验收通过,产品入口继续关闭。

工程执行16 / 16后端边界、路由、wire contract、iOS 判定器与文档齐全
工程收尾16 / 16K16 代码、门禁、观测、停止与回滚已完成
生产试点延期当前无真实用户,不维护 20–100 人阶段队列
连续观察延期真实用户窗口出现后再重新开始计时
01
正式 App 编译接线已完成

通过 App 已有的 IMClientPluginBridge 聚合层链接唯一 Shipping 产品;真实 App 编译和供应链门禁均通过。

02
签名 TestFlight延期

Run #82057 路径守卫已通过;自动打包机在需要真人窗口时再运行。

03
20–100 账号延期

服务端约束鉴权 actor 与每一个消息参与者;当前无真实用户。

04
回滚与隐私扫描已完成

停止、回滚与隐私门禁已经保留在工程主线。

05
连续十天指标DEFERRED

观测与停止合同保留;当前一人团队裁定延期。

06
真人验收延期

以后在真实用户窗口中补离线、重启、重试与多设备场景。

本刀真实修复路由、wire contract 与 App 编译依赖三处闭环

K16 已修复后端路由和 snake_case 合同,并完成 5 个隔离模块 → 1 个 Shipping 产品。PR #133 完成 App 编译接线;PR #134 恢复 200 个真实 UTF-8 路径;发布编排 PR #27 修复隔离身份合同。自动打包机按需运行,生产门禁继续关闭。

contract sha256 · 1a8ce8b90ec8382938462489742484bf48184b3fdae28398a435453ef41562fe
当前裁决:工程完成,运行验证延期,产品入口未开放统一装配产品 1/1 · App 编译接线 1/1 · 工程 16/16 · 产品入口 0 · 生产试点与观察延期

CAPABILITY GAP

和 WhatsApp 级别的差距,逐项说清

“有加密代码”不等于“默认 E2EE”。差距集中在设备身份、逐消息密钥、盲投递、Push 和媒体边界。

能力当前Private Chat v1 目标刀次
每设备密码学身份K05 域模型与签名投影已合并;运行时接口尚未暴露设备独立私钥,与账号授权链签名绑定K05
异步首次建链K09 已接入默认关闭的 reserve / commit API;产品门禁仍关闭signed prekey + one-time prekey + 独立 private_v1 会话K06–K09
逐消息密钥演进K10 已封装逐设备 Olm;K16 Shipping 产品已进入 App 编译图,运行门禁固定 falseOlm ratchet + 原子状态持久化 + 业务 AdapterK03–K10
服务端盲投递K09 已接 SQL Store 与迁移角色;运行时开关默认关闭TTL / ACK / 幂等 / 乱序的密文 envelope 信箱K08–K09
WebSocket / Push 隐私K09 已实现密文 WS 与仅含 schema/kind 的通用 Push;尚未开放给 AppWS 传 envelope,Push 只通用唤醒K09
iOS 私密文本闭环隔离双端闭环已通过;K10/K11/K12/K15/K16 已聚合并进入 App 编译图,但产品入口和 private_v1 会话仍为 0离线、重启、重试后仍不丢不重不明文K10–K11
设备本地数据保护K12 已验证仅本机 Keychain、完整文件保护、加密状态与认证后内存搜索;编译接线 1/1,运行入口 0私钥与本地明文只在受保护设备边界内可用K12
私聊密文媒体K14 已完成客户端分块 AEAD、直传 S3、断点续传、Range 回读与逻辑删除;编译接线 1/1,运行入口 0客户端流式 AEAD,S3 只存密文K13–K14
新消息多设备K15 已完成最新活跃名单、逐设备独立密文、原子批次与撤销隔离;编译接线 1/1,运行入口 0发送端逐已授权设备 fan-outK15
封闭试点门禁K16 App 编译接线、后端边界、观测、停止与回滚已完成;签名 build、真人试点与观察延期以后有真实用户时按需恢复 TestFlight 与观察K16

REPOSITORY OWNERSHIP

每个仓库不仅要知道做什么,还要知道绝对不做什么

最危险的不是少一个微服务,而是消息密钥、正文索引和媒体解密悄悄落到了错误的边界内。

matrix-x-chat-ios
负责
协议库适配、设备私钥、逐设备加密、本地明文、安全 UI
不负责
缺 key 时把 Private Chat 当普通正文发出
im-core
负责
公钥/预密钥目录、盲信箱、TTL、ACK、幂等、密文 WS 和唤醒
不负责
解密、索引正文、解析私聊 command、保存私钥
reits-auth
负责
登录会话、可信设备 step-up、设备授权与撤销
不负责
保存消息密钥,或把 OAuth session 当 E2EE identity
reits-media
负责
预签名、S3 密文对象、配额、checksum 和 lifecycle
不负责
解密私聊媒体、扫描原文件、保存媒体 key
im-media-send-kit
负责
项目中立的流式加密、分片和 descriptor
不负责
知道具体聊天、用户和 CDN 域名

FOUNDATION EVIDENCE · K01—K16

旧 16 刀是安全基础证据,不冒充当前迁移进度。

K01–K16 证明协议、盲信箱、密文媒体与失败关闭能够实现;当前产品进度按开发规划中的 L01–L15计算。签名 App、真实账号、10 天观察与真人 TestFlight 已转为延期运行项,不再阻塞工程 15/15。

G0K01

先说真话

业务收益停止假安全承诺,降低品牌与合规风险

工程验收正式 UI、文档和真实行为一致

G1K02–K04

证明可行

业务收益知道是否值得继续投入,不在生产上试算法

工程验收威胁模型、许可证结论与官方 Olm 状态机 POC

G2K05–K09

让服务端失明

业务收益数据泄漏半径从正文收缩为最小投递元数据

工程验收设备目录、预密钥、盲信箱和通用 Push

G3K10–K12

文本工程闭环

业务收益具备正式 App 装配前提,但不提前开放用户

工程验收两台 iOS 离线、重启、重试和本地数据保护

G4K13–K15

扩展媒体与多设备

业务收益从私密文本走向完整私聊体验

工程验收密文媒体和已授权设备新消息 fan-out

G5K16

运行验证

业务收益真实用户出现后再恢复运行验证,不继续消耗当前一人团队

工程验收观测、停止与回滚代码保留;真人账号和 10 天观察延期

完整刀账与验收附件只在 Knowledge 维护Developer Portal 不再复制 K01–K16 或 L01–L15 的逐刀文档

ACCEPTANCE · STOP CONDITIONS

安全项目的进度,必须能用“什么时候立刻停”来衡量

任意一条停止条件命中,试点都必须停止扩张;不允许为了“刀数进度”将安全问题改成非阻断。

01

任意 Private Chat 明文回退

02

服务端、日志、Push 或 S3 出现消息正文

03

被撤销设备仍取得新 envelope

04

升级导致已有私密消息永久不可解

05

协议库许可证或 TestFlight 分发权不明确

06

发现可批量解密或静默注入设备

07

Crash-free session 低于 99.5% 或投递成功率低于 99.9%

正式 App 编译接线已完成

PR #133 已合并;复用既有桥接依赖,不修改受保护的 pbxproj,产品入口继续关闭。

签名发布候选1 个 build

只在发布编排仓对精确合并 SHA 归档、签名并上传 TestFlight。

封闭试点规模20–100

双方账号都在组内;当前生产账号数为 0。

真实观察延期

以后重新启用时仍按完整窗口执行,不回填历史数据。