Files
qinglong/docs/adr/ADR-0384-strong-cluster-run-stop-management.md
T

6.6 KiB
Raw Blame History

ADR-0384:强认证的 Cluster Run Stop Management

  • 状态:Accepted
  • 日期:2026-08-12
  • 关联 RFCQL-RFC-0001 D-296
  • 前置决策:ADR-0005、ADR-0039、ADR-0056、ADR-0372、ADR-0383
  • SupersedesADR-0383 中“ql3_run_manager 没有更新既有 Run 权限”的最小权限定义;其余进程、认证、部署与 package 决策保持有效

上下文

ADR-0383 已建立独立、强认证、显式启用的 Cluster Run Management Plane,但产品面只暴露 run.retry。Cluster Control 已有内部 cancellation repository,直接把它接到产品 route 会留下三个缺口:允许审计与取消意图不在同一事务、专用管理角色没有精确写权限、调用方可能绕过 Run Management 的 purpose-bound OIDC 与五分钟强认证。

QingLong 同时面向低资源路由设备和多节点集群。本能力不能给 Edge/Standalone 增加常驻成本,也不能为单个命令新增浅 package、独立进程、连接池或部署 overlay。

决策

1. 扩展既有内聚领域,不新增 package 或进程

run.stoprun.retry 复用 @qinglong/cluster-admin/run-management 的 service、discriminated transport、HTTPS route、client、OIDC keyset、mTLS listener、PostgreSQL Pool 和 operations/run-management 部署。PostgreSQL adapter 继续由 @qinglong/cluster-postgres/run-manager 发布。

默认 Edge、Standalone、Cluster base overlay 均不加载该能力;关闭 Run Management 时仍为零新增进程、listener、Pool、timer、watcher、cache、sidecar 与 Cluster dependency。这里以“领域内聚 + 独立部署生命周期”决定 package 粒度,不以文件数量决定 package 数量。

2. 固定强认证命令与服务端身份

transport 只接受 operation=run.stop、Project/Run identity、UUID mutation identity 和低敏 request/audit identity,不接受 caller 提供 Event ID、时间、取消原因、Run version 或状态。服务端生成 canonical qinglong/run-cancellation@v1 Event ID,并固定 cancel_reason=user

操作必须同时满足 mTLS、run-management purpose-bound OIDC、五分钟内 multi_factor|hardware User 和 run.stop Policy。route admission 与 PostgreSQL 事务分别重验身份和 Project/RoleBinding fence;不存在继续遮蔽,终态或 durable fence 漂移稳定映射为 conflict。

3. 取消意图与允许审计原子提交

PostgreSQL repository 在一个 SERIALIZABLE 事务中使用数据库时钟,锁定 Run,重验 lock_run_management_policy_fence,写入 cancel_requested_at_mscancel_reason、Run versionevent_sequence,追加 immutable cancellation Event 和 run.stop allowed security audit。任一写入失败都整体回滚;拒绝或不可用由 service 写独立 failure audit。

相同 mutation 的重放必须返回 already_requested,并验证已有 Event 与 allowed audit 的精确语义;不同 mutation 不能覆写既有取消意图。terminal Run 不接受新的 stop。该操作只记录 durable intent,实际 Attempt/Run 收敛仍由既有 cancellation dispatch、lease/fencing 与 recovery authority 完成。

4. PostgreSQL 权限按列收窄

Migration pg-0057-run-management-stop-boundary 把 control-core contract 提升到 v56,并添加 run_management_stop capability。ql3_run_manager 不获得 Runs 表级 UPDATE,只获得以下四列的 column-level UPDATE

  • cancel_requested_at_ms
  • cancel_reason
  • version
  • event_sequence

readiness 同时证明四列可更新、status 不可更新、表级 UPDATE 仍为 false。角色不得改变 Run 状态、Project/RoleBinding、Task、execution revision,且继续没有 DELETE、migration、Worker、AI 或 Approval authority。

验收

  • service/transport/client 测试覆盖 stop、强身份、命令 shape、response drift、原子 allowed audit 与稳定错误映射;
  • PostgreSQL 测试覆盖 v56 checksum/capability、精确列权限、事务顺序、exact replay、fence 漂移和回滚;
  • 真实 PostgreSQL 18.4 physical HA 以两个独立 ql3_run_manager Pool 证明跨 Pool replay、允许审计同步复制与 promotion 后写入;
  • 完整 18-package clean build/test、backend、dependency/package/deployment/Profile artifact、GitNexus change scope 全部通过后才允许阶段性提交。

被否决的替代方案

  1. 新增 @qinglong/run-stop package:没有独立依赖、制品或部署生命周期,只会制造浅 package。
  2. 新增 stop listener/Pool/overlay:与 retry 共享同一认证和资源边界,会重复常驻成本。
  3. 授予 Runs 表级 UPDATE:会允许管理角色修改状态与其他控制字段,超出产品操作所需。
  4. 先写 allowed audit、再写取消意图:可能留下“审计显示成功但意图未提交”的错误事实。
  5. 由调用方提交 Event ID 或 cancel reason:扩大重放和语义漂移表面。

验收证据(2026-08-12

  • @qinglong/cluster-admin:284 pass、2 个外部集成条件 skip、0 fail;@qinglong/cluster-postgres:311 pass、1 个外部数据库条件 skip、0 fail;完整 18-package clean build/test 全部退出 0
  • backend 1,167 项中 1,165 pass、2 个环境条件 skip、0 failpackage/dependency/Edge import/Cluster deployment/CloudNativePG/Local image 静态门均 compatible、零 finding
  • workspace 保持 18 个 package、1,071 个 source、1,053 个 nestedsingleSourcePackages=[]shallowSourcePackages=[]cluster-postgres 为 153/152v56 migration 归入既有 run-management 领域,没有新增浅 package
  • 14 档 Edge/Standalone Profile artifact 全部 compatible;最小 Edge 仍仅包含 Local SQLite、Runtime Core 与 semver,产物 2,459,624 bytes、53 个 loaded module,未引入 Cluster/PostgreSQL
  • PostgreSQL 18.4 arm64 physical HA 通过 123 gates、timeline 1→2,证明列级 UPDATE readiness、双 Run Manager Pool exact replay、allowed audit 同步复制、既有 cancellation convergence、旧主 fencing,以及恢复 remote_apply 同步冗余后的 promotion stop;报告 SHA-256 2e5759d3b5e62cd571f6c31450aec0d7f611fa8cafd727b7bb25471792e83c29,独立离线审计 compatible:true、零 finding。

影响

  • PostgreSQL schema contract 从 v55 升至 v56;启用新版 Run Management 前必须先运行 migration 和 readiness
  • Cluster Run Management route 成为 retry | stop 的严格判别联合,但既有 retry envelope/response 保持兼容;
  • 低配设备默认资源与依赖闭包不变;集群只在已选择的 Run Management workload 内增加同一 Pool 上的一类短事务;
  • UI 后续可以复用同一 transport 展示 durable cancellation intent,但不得直接写 Run 状态或绕过强认证。