feat(ql3): establish 3.0 incubation baseline

This commit is contained in:
whyour
2026-08-12 00:25:26 +08:00
parent 4bf92dcfeb
commit c699c32461
2817 changed files with 779642 additions and 653 deletions
@@ -0,0 +1,128 @@
# ADR-0183:本机 Publisher Key 紧急撤销与隔离证据
- 状态:Accepted
- 日期:2026-07-28
- 关联:RFC D-133、D-169、D-170、D-171、D-172、D-173ADR-0135、
ADR-0179、ADR-0180、ADR-0181、ADR-0182
## 背景
ADR-0182 的正常退休要求旧 signer 引用和未决 catalog transaction 都归零,这不适合
疑似或确认泄露的 key。继续等待重签与 collect 会允许攻击者发布新的 recovery
entry;直接删 key 又会把“信任根已删除”误写成“已经运行的 Package、Task 和 Tool
均已停止”,并遗漏受影响 durable lock 的审计锚点。
本机 trust、catalog/bundle 文件与 SQLite 仍是不同介质。紧急动作必须先建立一个跨
重启可见的阻断事实,再以双人或显式 break-glass 完成不可逆删除;不能依赖进程内
锁、watcher 或一次目录扫描。
## 决策
### 1. 提案先阻断,再确认删除
第一位 authenticated current Owner 执行
`plugin-package.publisher-trust.revoke.propose`。短生命周期命令先有界分析全部
retained catalog entry 和未决 transaction,并把受影响 lock digest 的排序集合、
计数、publisher/key、expected generation、mutation、提案 Owner 与 audit 时间绑定
为 immutable proposal 和 `impactDigest`
proposal 以 hard-link no-replace 写入受管 `0700` trust root;一旦 durable
- 目标 signer 的 catalog publication 立即失败;
- application 在 queued stage 前和 staging 后、返回 evidence 前各复验阻断事实;
- rotate、retire 和另一生命周期 mutation 不能越过该 pending proposal
- 命令返回 `runtimeAction=stop_required`,要求 operator 停止 application。
proposal 不提供 abort 或 unblock。疑似泄露事实一旦发布就只能通过精确确认继续,
避免删除提案恢复已受怀疑 signer 的 authority。
### 2. 默认双人确认,break-glass 必须显式绑定影响
第二条命令 `plugin-package.publisher-trust.revoke.confirm` 必须精确重放 proposal 的
publisher、key、expected generation、mutation、`proposerSubjectId`
`expectedImpactDigest`,并选择:
- `dual_control`:确认者与提案者必须是两个不同 subject,且两者在确认时都仍是
current default Project Owner
- `break_glass`:允许同一 current Owner 独立完成,但必须显式选择该模式,并提交
`suspected_key_compromise``confirmed_key_compromise` reason code。
两种模式都重新执行强认证、current Owner fence 和既有低敏 SecurityAudit。确认后先
写 immutable revocation receipt,再生成显式 `revoke` snapshotsnapshot 必须精确
等于前一 generation 删除一个目标 key,不得改写其他 key。
紧急撤销允许删除最后一个 key。此时 `current.json` 的空 key 集合是可恢复、可审计的
管理状态,但 runtime trust registry 构造失败关闭;operator 必须通过受审 provision/
recovery 流程重建信任,不能让 runtime 使用隐式默认 key。
### 3. Quarantine 是不可变证据,不是假热停止
receipt 保存 proposal 时观察到的受影响 lock digest 集合,并在 inspect 中只聚合返回
`quarantinedLockCount`,不回显 publisher、key 或 lock identity。它证明这些 lock
必须按 compromise 处置,但本切片不修改既有 Package installation 状态枚举,也不
声称已撤下:
- 已经 `active` 的 Package
- 已物化的 Task/Tool resource generation
- 已进入 `staged``activating` 的事务。
确认成功返回 `runtimeAction=restart_required`。这不是自动重启许可:operator 应在
停机状态审查受影响 lock、替代 key 与恢复源。后续 D-174 必须新增持久化
Package deactivation/quarantine 状态机,并让 Task/Tool publication 和 invocation
admission 按 durable fence 撤出已激活资源。
### 4. 恢复、容量与低配约束
proposal、receipt、snapshot 或 current 提升任一窗口崩溃,只允许同一 authenticated
command 和同一 impact/authorization/reason 精确重放;漂移失败关闭。trust root
最多保留 32 个 revocation proposal、32 个 receipt、32 组 retirement evidence、
64 代 snapshot 和 64 个临时文件;未知或超限 entry 失败关闭。
实现复用已有:
- `@qinglong/local-admin/package-publisher-trust`
- `@qinglong/local-admin/package-recovery-catalog`
- `@qinglong/local-owner-cli/package-publisher-trust-command`
- `@qinglong/local-application/plugin-package-recovery-catalog`
没有新增 workspace package、第三方依赖、timer、watcher、listener、socket 或 steady
state I/O。空队列仍不加载 catalogproposal guard 只在真实 publication/stage 或
显式管理命令中读取有界私有目录,适合低配路由设备。
## 拒绝方案
1. **复用正常 retirement**:要求引用为零,无法立即冻结疑似泄露 signer。
2. **单命令立即删除**:缺少第二人复核或显式 break-glass,误操作不可审计。
3. **只删除 trust key**:丢失受影响 lock 集合,也无法驱动后续资源隔离。
4. **新增 `quarantined` 枚举但不接资源消费者**:形成“状态已安全”的虚假保证。
5. **进程内 denylist 或 watcher**:重启丢失且增加路由器 idle 资源和竞态。
6. **删除最后 key 时注入默认 key**:在最危险窗口引入未审计信任根。
## 当前证据
- proposal durable 后目标 signer 的 catalog publish 与 queued application stage 均
失败关闭;
- 同一 Owner 使用 `dual_control` 被拒绝,显式 `break_glass` 可完成产品级流程;
- core 双 Owner 流程验证不同 subject、impact digest、reason 和 authorization mode
- receipt/snapshot/current 崩溃窗口由 exact command 收敛,最后 key 可撤销且 runtime
registry 失败关闭;
- inspect 只返回 revocation、pending 和 quarantined lock 计数;
- 非 Owner 在 proposal 可见前被拒绝,33 个 revocation evidence 触发容量失败关闭;
- local-admin 63/63、local-application 32/32、local-owner-cli 22/22、
dependency/source boundary 30/30 和 Edge import 121 modules 全绿;
- edge/standalone application 为 4,766,330/4,766,474 bytes、607 files、90 loaded
modulesapplication-ai 为 5,444,151/5,444,307 bytes、651 files、89 loaded
modules,四种制品和 RSS 门均在预算内;
- workspace 仍为 22 package,无新增生产依赖或常驻资源。
Cluster 代码、migration、ACL 和部署 manifest 未变化。本 ADR 不声明 Cluster publisher
trust 能力;PostgreSQL HA Docker 门只在后续 Cluster 对等实现发生变更时重跑。
## 后续门禁
1. D-174active/staged/activating Package 的持久 deactivation/quarantine
2. Task/Tool resource generation 撤回、invocation admission fence 与 crash replay
3. 被隔离 lock 的替代发布、恢复或永久 tombstone ceremony
4. 在线 OCI fetch authority 与 publisher metadata/update channel
5. 固定低配 Linux 路由器断电、ENOSPC、闪存写放大与容量证据;
6. Cluster 对等 trust lifecycle 和双人管理 transport。