Files
qinglong/docs/adr/ADR-0443-deployment-ready-terminal-release-finalization.md
T

6.8 KiB
Raw Blame History

ADR-0443Deployment-ready 的终态 Release Finalization

  • 状态:Accepted
  • 日期:2026-08-18
  • 关联 RFCQL-RFC-0001 D-03、D-14、D-336、D-344、D-345、D-350、D-351
  • 关联 ADRADR-0436、ADR-0437、ADR-0441、ADR-0442
  • SupersedesADR-0442 中“catalog receipt attested 后即可 mutation 最终 image tag”的发布顺序
  • Amended byADR-0444 将最终 tag mutation 从 YAML heredoc 收敛为 pre-registry validated、可重放演练的独立 finalizer

上下文

ADR-0442 已把最终 image tag 从 release-set 聚合点后移到 immutable catalog 建立并验签之后,但 Local Compose 与 Cluster K3s 下游门仍在该次 tag mutation 之后运行。若 catalog 可验证而 Edge、Standalone 或三节点 K3s 的真实部署链失败,公开 versionTag/sourceTag 已经存在,却没有与本次 scope 对应的 catalog-bound 部署证据。此时“catalog-ready”只证明发布材料完整,不能证明 该发布已进入要求的部署族。

同时,部署 job 原先只上传 content-free report,不保留生成 report 时独立消费的 catalog ceremony bundle。终态发布者无法证明 report 确实来自与自身复验相同的 immutable catalog,也无法在一个可离线审计的 readiness receipt 中闭合 catalog、scope 和部署结果。

决策

  1. release-set job 只负责聚合、审计、签证 release-set,发布并验证 immutable OCI catalog,以及签证 catalog receipt。它不再拥有最终 image tag mutation、registry login 或 publication closure 权限。
  2. local|all 必须成功完成 Edge 与 Standalone 两个正式 Compose rolloutcluster|all 必须成功完成 catalog-bound 三节点 K3s install、Head 和 fenced retirement。终态 release-finalization 使用显式 needs/result 真值表,要求当前 scope 的 job 全部 success,不属于 当前 scope 的 job 必须为 skippedfailurecancelled 或意外运行均失败关闭。
  3. 每个部署 evidence artifact 必须同时保留 owner-private、canonical、exact-three-file catalog consumption bundle 和 content-free report。 Local artifact 精确为 consumption 三文件、edge.jsonstandalone.jsonCluster artifact 精确为 consumption 三文件、report.json。 finalizer 下载后重新固定目录 0700、文件 0600 并拒绝缺失或额外文件。
  4. finalizer 不信任 publisher 或部署 job 的瞬时内存。它再次从 discovery ref 解析 immutable catalog,独立执行 Cosign、GitHub provenance、 manifest round-trip 与 ceremony audit,并从自己读取的 bytes 重建 catalog plan/receipt。
  5. 新增 qinglong/release-deployment-readiness-receipt@v1。它联合审计 finalizer consumption、当前 scope 要求的每个 deployment consumption bundle 和 report,绑定 release identity、immutable catalog reference、manifest/release-set digest、每份 consumption/report digest、精确部署族和清理结果。它拒绝 synthetic fixture、不完整报告、catalog 脱离、跨 scope 证据和未清理现场。
  6. readiness receipt 必须在 Docker login 和任何 tag mutation 之前生成、复审并单独 attested。只有该 attestation 成功,finalizer 才生成并执行 qinglong/release-publication-plan@v2。v2 plan 和 qinglong/release-publication-closure-receipt@v2 都绑定 readiness receipt digest、 finalizer consumption digest 和精确部署族,发布 authority 升为 verified_catalog_bound_deployments
  7. D-350 的 bounded inventory、全量 conflict preflight、exact-tag reuse、absent-tag copy、最终逐 tag 回读和无 CAS/跨仓库事务声明保持不变。 它们只从 catalog publisher 移入唯一的 finalizer,并发生在 readiness attestation 之后。
  8. 90 天最终 bundle 保存 finalizer consumption、scope-exact deployment evidence、readiness receipt、publication plan、tag observation 与 closure receipt。部署 authority 仍是签名并 attested 的 immutable catalog digestmutable tag 与 closure 只表示发布可见性和终态证据。

失败与恢复

  • catalog 已发布但任一要求的部署门失败:没有最终 image tag mutation。该 catalog 是可复验候选材料,不是 deployment-ready tag authority。
  • evidence artifact 缺失、额外、权限过宽、包含 synthetic report 或引用不同 catalogfinalizer 在 registry login 前失败。
  • readiness attestation 失败:不发布 tag;同一 protected source tag 可重跑并重新取得现场证据。
  • tag promotion 中途 response loss:继续使用 ADR-0442 的 exact-tag reuse,仅补 absent tag;不同 digest 永远冲突失败。
  • readiness receipt 是本次部署运行的操作证据,其 digest 可以随新的真实 consumption/report 变化;它不重新定义 release-set 或 immutable catalog identity,也不伪称跨重跑逐字节确定。

部署与资源影响

  • Edge、Standalone、低配路由设备和 Cluster 节点不安装 Node、regctl、Cosign 或 GitHub CLI,不新增 watcher、timer、listener、updater、 queue、缓存或常驻进程。
  • 不新增 workspace package、生产依赖、数据库、schema、migration、SQL、Kubernetes object、RBAC 或业务副本。
  • 增量 CPU、内存、网络和磁盘只发生在短生命周期 release runner。Local scope 不运行 K3s 门,Cluster scope 不运行 Compose 门;all 才运行两族。

被拒绝的替代方案

catalog-ready 后继续立即发布最终 tag

拒绝。catalog 完整不等于 scope 要求的部署路径已成功,仍会留下“公开 tag 成功、真实部署失败”的窗口。

只依赖 GitHub job result,不闭合部署证据

拒绝。瞬时调度状态不能证明 report 使用了哪个 immutable catalog,也无法让最终 bundle 独立审计。

让部署 job 自行发布 tag

拒绝。会把 package write、attestation write 和 registry login 权限扩散到多个高成本 runner,并引入多写者竞争。

把完整 token、kubeconfig 或命令 transcript 上传给 finalizer

拒绝。finalizer 只需要 owner-private catalog bundle 和 content-free bounded reportcredential 与现场控制材料必须留在原 job 生命周期内。

验证

  • readiness contract 覆盖 Local/Cluster/All 精确部署族、缺失/额外/跨 scope 证据、catalog 脱离、synthetic/incomplete/unclean report、 receipt tamper、自摘要重算和 closed CLI
  • release workflow 静态门固定 catalog receipt → scope-exact deployment jobs → finalizer independent consumption → readiness audit/attestation → tag mutation → closure audit/attestation 顺序,并拒绝 evidence bundle、needs/result、独立 attestation 或最终 bundle 漂移;
  • 完整仓库、产物档位和部署 Gate 的阶段结果记录在 QL-RFC-0001 D-351;首份真实 GHCR deployment-ready finalization 仍须由受保护 v3 release tag 或受控 release repository 演练产生。