5.7 KiB
ADR-0084:版本化 Owner Delivery Acknowledgement 压缩与重放 Tombstone
- 状态:Proposed(核心、GC CLI 与本机自动化门禁已完成;Linux/路由器和故障注入门禁待实现)
- 日期:2026-07-21
- 关联 RFC:QL-RFC-0001 D-75、D-81、D-82
- 关联 ADR:ADR-0079、ADR-0081、ADR-0082、ADR-0083
上下文
QingLong3LocalOwnerDeliveryAcknowledgements 让确认后的 credential/challenge mutation 在交付目录已清空时仍能于 entropy 生成前 exact replay。直接删除旧行会让 service 再次创建 CSPRNG candidate;即使 provisioning/challenge 的 mutation 唯一约束最终拒绝写入,也已经违反“不重新生成 secret”,并可能留下新的 pending 文件。
账本 retention 因此不能等同于 DELETE WHERE acknowledged_at_ms < ?。需要把完整 acknowledgement 压缩为仍可在生成 entropy 前识别、可从 immutable source 重建并能检测 source 漂移的 tombstone。
决策
1. 压缩而非遗忘 mutation
GC 在唯一 SQLite authority 的一个 BEGIN IMMEDIATE 中完成:验证完整 acknowledgement 与 provisioning/challenge source、插入 versioned GC/tombstone、写低敏 audit、删除完整 acknowledgement。tombstone 至少绑定原 mutation、kind、delivery digest、首次确认时间、完整 acknowledgement semantic digest、retention policy、bridge-clear evidence 与 GC mutation。
resolveDeliveryAcknowledgement 先读完整账本;不存在时读取 tombstone并从 immutable provisioning/challenge source 重建 acknowledgement,再比较 semantic digest。完整行与 tombstone 同时存在、source 缺失或摘要漂移均 fail closed。service 因而仍在 entropy 生成前返回 existing/null。
2. 文件 crash bridge 必须先证明为空
短生命周期文件 authority 对目标 mutation 执行一次已有 64 项硬上限目录扫描,并确认 .pending.json、.ready.json、.acknowledged.json 三个精确名称均不存在。bridge-clear evidence 绑定目录 device/inode、kind、mutation 和 authority-owned 当前时间;GC command 不接受调用方时间,也不允许只凭“文件当前不存在”的布尔值删除。
3. Retention 与 source 终态共同裁决
v1 policy 的 replay retention 和 audit retention 最低均为 30 天、最高 10 年。credential acknowledgement 只有在 credential 已过期或 latest version 已 revoked,且没有涉及它的未完成 credential recovery 时才可压缩;challenge 必须已 claim 或过期。eligible time 至少取 acknowledgement+replay retention、source expiry/terminal time以及相关 issue/claim/provision audit+audit retention 的最大值。
4. 只存在于短生命周期 authority
常驻 runtime/application 不扫描候选、不持有 timer,也不取得 GC repository。最终组合根必须显式指定单个 mutation 或最多 64 项的有界页;默认不自动压缩。edge/standalone 常驻制品的 package、文件和 RSS 门禁不得因该能力增加。
被否决的替代方案
- 按时间直接删除 acknowledgement:会重新进入 entropy 路径,拒绝。
- 永久保留完整行:安全但未完成 retention/数据最小化目标,拒绝作为最终状态。
- 只保留 mutation ID:无法验证历史 delivery digest、首次确认时间和 source 漂移,拒绝。
- GC 时扫描整个 outbox 或账本:成本随历史增长,不适合路由设备,拒绝。
- application timer 自动清理:把短生命周期管理 authority 注入常驻运行面,拒绝。
分阶段实现与验收
- contract(已完成):exact-shape GC command、固定审计身份、30 天最低保留、10 年上限、bridge-clear evidence 绑定及 acknowledgement semantic digest。
- 文件证据(已完成):
FileLocalOwnerBootstrapSecretDelivery.inspectBridgeClear使用已有目录硬上限并拒绝任一目标桥文件存在。 - SQLite(已完成):
0025/0026reviewed migration、capability v13、typed schema/readiness、credential/challenge tombstone reconstruction、source terminal/reference/retention 裁决,以及 audit+tombstone+完整行删除的单个BEGIN IMMEDIATEtransaction;双连接 winner、mutation conflict、active reference 与 entropy-free replay 均有测试。 - 组合根(已完成):
@qinglong/local-owner-maintenance/acknowledgement-gc只接受目标 mutation/kind/delivery digest,使用 authority-owned clock,从受 inode 约束且 64 项有界的 delivery directory 生成 evidence,再调用专用 SQLite/acknowledgement-gc;maintenance 不提供聚合根入口,无 timer,常驻入口不可导入。 - 本机门禁(已完成):ADR-0087 与 ADR-0106 物理合并后 21 个 importer dependency audit、联网 production vulnerability audit、全包测试、六种常驻制品闭包和 edge import audit 均须持续通过;console 内部 ceremony 与 maintenance/CLI authority 未进入闭包。
- GC CLI(已完成):ADR-0085 的 command adapter 与
ql3-owner-gcbin 已并入@qinglong/local-owner-maintenance;它只接受0600durable command file,经同包相对模块复用两个受审 authority 并只输出低敏结果,不直接取得 SQLite 或 destructive keyring 子入口。旧@qinglong/local-owner-gc-cli名称为 dependency tombstone。 - 实机门禁(待实现):Linux x64/arm64、物理路由器、断电窗口与真实 ENOSPC/EROFS 证据。
未完成项
核心与受审单次 GC CLI 已能安全压缩 acknowledgement,但仍不得据此自动启用 production GC:Linux/路由器、断电和真实存储故障门禁尚未完成。ADR-0082 的“不遗忘 mutation”长期 retention 架构项已由本 ADR 闭环;fresh Owner 与远程产品入口仍保持默认关闭。