Files
getDomain/docs/schemas/release_hub_contract.md
2026-04-18 23:52:51 +08:00

13 KiB
Raw Permalink Blame History

domainCheck Release Hub Contract

1. 目标

这份文档用于冻结 Release / Rollout / Launchpad / Gate 的正式 contract。

核心原则:

  • 先有 Release再有 Rollout
  • Release 是不可变版本对象
  • Rollout 是分批推进对象
  • Gate 是是否可发的统一门禁对象
  • Launchpad 是给页面与 Codex 消费的发布驾驶舱对象

建议与 ops_job_contract.md 配套阅读,因为 Rollout 的真正执行颗粒度最终仍然是 ops job


2. Release Object

来源:

  • POST /api/v1/ops/releases
  • GET /api/v1/ops/releases
  • GET /api/v1/ops/releases/latest
  • GET /api/v1/ops/releases/{id}
  • POST /api/v1/ops/releases/{id}/activate

最小字段:

{
  "id": 1,
  "release_version": "2026.04.18+bd6bcb2",
  "channel": "stable",
  "commit_sha": "bd6bcb2",
  "status": "ready",
  "status_label": "已就绪",
  "artifact_url": "https://release.example.com/domaincheck-2026.04.18.tgz",
  "checksum": "sha256:...",
  "notes": "",
  "metadata": {},
  "created_by": "www",
  "created_at": "2026-04-18 05:30:00",
  "activated_at": "2026-04-18 05:35:00",
  "summary": "2026.04.18+bd6bcb2 已就绪,制品与校验信息齐备,可进入 Rollout。",
  "summary_text": "2026.04.18+bd6bcb2 已就绪,制品与校验信息齐备,可进入 Rollout。",
  "focus_ref": {
    "kind": "release_hub",
    "release_id": 1,
    "release_version": "2026.04.18+bd6bcb2",
    "channel": "stable",
    "rollout_id": 0,
    "rollout_code": "",
    "section": "release_detail"
  }
}

约束:

  • 同一 release_version 只对应一份发布物
  • Release 创建后不应重新指向另一份 artifact
  • artifact_url + checksum 是发布可验证性的最小基线

推荐状态:

  • draft
  • ready
  • active
  • archived

3. Rollout Object

来源:

  • POST /api/v1/ops/releases/{id}/rollouts
  • GET /api/v1/ops/rollouts/{id}
  • GET /api/v1/ops/rollouts/{id}/jobs
  • POST /api/v1/ops/rollouts/{id}/advance

最小字段:

{
  "id": 11,
  "release_id": 1,
  "rollout_code": "rollout-20260418-001",
  "target_selector": {
    "region": "mainland",
    "role": "worker"
  },
  "target_nodes": [
    "mainland-worker-01",
    "mainland-controller-01"
  ],
  "policy": {
    "batch_size": 1,
    "require_approval_between_batches": true,
    "rollback_on_failure": true
  },
  "status": "running",
  "status_label": "执行中",
  "batch_cursor": 1,
  "batches_total": 2,
  "jobs_total": 2,
  "jobs_created": 1,
  "result_summary": {},
  "target_node_codes": [
    "mainland-worker-01",
    "mainland-controller-01"
  ],
  "summary": "当前已覆盖 1/2 台节点,仍有 1 条任务执行中。",
  "summary_text": "当前已覆盖 1/2 台节点,仍有 1 条任务执行中。",
  "focus_ref": {
    "kind": "release_rollout",
    "rollout_id": 11,
    "rollout_code": "rollout-20260418-001",
    "release_id": 1,
    "section": "rollout_jobs"
  }
}

正式定义:

某个 Release 在某批目标节点上的一次分批推进计划

推荐状态:

  • planned
  • running
  • awaiting_approval
  • ready_for_next_batch
  • halted
  • completed
  • completed_with_issues

4. Default Rollout Gate

来源:

  • GET /api/v1/ops/overview
  • overview.release_hub.default_rollout_gate

这层是 Release Hub 最关键的后端 gate contract。

最小字段:

{
  "status": "attention",
  "status_label": "待处理",
  "status_type": "warning",
  "summary": "当前已有 Release但默认目标节点中仍有未接管或未通过巡检的节点。",
  "summary_text": "当前已有 Release但默认目标节点中仍有未接管或未通过巡检的节点。",
  "release": {
    "id": 1,
    "release_version": "2026.04.18+bd6bcb2",
    "status": "ready",
    "status_label": "已就绪"
  },
  "execution_mode": "remote-agent",
  "execution_mode_label": "Node Agent",
  "target_node_codes": [
    "mainland-worker-01"
  ],
  "default_target_node_codes": [
    "mainland-worker-01"
  ],
  "blocking_reasons": [],
  "warning_reasons": [
    "存在未通过标准巡检的节点"
  ],
  "recommendations": [
    "先执行标准巡检,再进入 Rollout"
  ],
  "operational_readiness": {
    "summary": "remote-agent 就绪 1/2标准巡检通过 1/2",
    "rows": []
  },
  "focus_ref": {
    "kind": "release_hub",
    "release_id": 1,
    "release_version": "2026.04.18+bd6bcb2",
    "channel": "stable",
    "rollout_id": 0,
    "rollout_code": "",
    "section": "default_rollout_gate"
  }
}

推荐状态:

  • missing_release
  • release_not_ready
  • artifact_missing
  • no_targets
  • blocked
  • attention
  • ready

要求:

  • 首页驾驶建议
  • Release 页面门禁
  • Rollout 预检
  • Codex 自动驾驶

必须共用这同一份 Gate。


5. Default Rollout Execution

来源:

  • overview.release_hub.default_rollout_execution
  • overview.release_hub.default_rollout_gate_options

作用:

  • 告诉页面 / Codex 这轮默认应使用什么执行方式
  • 给出其他可选 gate / mode

最小字段:

{
  "recommended_mode": "remote-agent",
  "recommended_mode_label": "Node Agent",
  "recommended_gate": {},
  "gates": {
    "remote-agent": {},
    "ssh": {}
  }
}

推荐执行模式:

  • remote-agent
  • ssh
  • control-plane

说明:

  • 正式发布优先 remote-agent
  • ssh 只作为首发接管与紧急救援兜底
  • control-plane 不应用来承载大规模 Worker 发布

6. Release Launchpad

来源:

  • overview.release_hub.launchpad

作用:

  • 给页面与 Codex 提供更偏“驾驶舱”的发布聚合视角

最小字段:

{
  "latest_package": {},
  "latest_release": {},
  "worker_rollout_preview": {},
  "control_rollout_preview": {},
  "launchpad_status": {
    "status": "attention",
    "status_label": "待处理",
    "summary": "建议先完成 Worker 点状灰度,再决定是否推进控制面。",
    "summary_text": "建议先完成 Worker 点状灰度,再决定是否推进控制面。",
    "recommended_action_code": "open_release_deploy_worker",
    "recommended_target_node_code": "mainland-worker-01",
    "recommended_recovery_label": "签发接入工单",
    "recommended_recovery_summary": "当前节点仍处于接入阶段,建议先签发 onboarding.bootstrap。",
    "onboarding_bootstrap_pending_nodes": 1,
    "onboarding_acceptance_ready_nodes": 0,
    "recommended_mode": "remote-agent",
    "recommended_mode_label": "Node Agent",
    "focus_ref": {
      "kind": "release_hub",
      "release_id": 1,
      "release_version": "2026.04.18+bd6bcb2",
      "channel": "stable",
      "rollout_id": 0,
      "rollout_code": "",
      "section": "release_launchpad",
      "mode": "worker"
    }
  }
}

launchpad_status 至少应回答:

  • 当前先补什么
  • 推荐动作码是什么
  • 当前首个缺口节点是谁
  • 当前恢复动作的人类标签是什么
  • 当前缺口更偏“待接入”还是“待验收”
  • 推荐执行方式是什么
  • 先看 Worker 预案还是先看 Control 预案

正式约束:

  • recommended_target_node_code
    • 一旦 launchpad 已经收敛出首个缺口节点,就应直接返回
    • 页面、CLI、Codex 不应再分别从 gap rows 中自行挑第一台
  • recommended_recovery_label
    • 是给人看的动作标题,例如:
      • 签发接入工单
      • 补执行面接管
      • 执行接管验收
  • recommended_recovery_summary
    • 是解释“为什么当前默认不是发版,而是先补接管”的正式摘要
  • onboarding_bootstrap_pending_nodes / onboarding_acceptance_ready_nodes
    • 是 launchpad 汇总层面的正式计数
    • 允许被 go-live-summary、CLI 摘要、Codex brief 直接复用

7. 发布动作 contract

当前发布相关动作不应再退回“通用发任务”语义,而应正式区分:

  • deploy.release.control
  • deploy.release.worker
  • deploy.release.custom

这三个动作必须共用:

  • 同一份 Gate 判断
  • 同一份 Release 版本对象
  • 同一份 Rollout 编排结果

8. Artifact 不可变要求

上线前建议把 Release 供应链固定为:

  1. 构建产物
  2. 生成 checksum
  3. 生成 manifest
  4. 上传 artifact
  5. 创建 Release
  6. 激活 channel
  7. 创建 Rollout

Node Agent 侧部署链路要求:

  1. 下载 artifact
  2. 校验 checksum
  3. 解压到 releases/<version>
  4. 切换 current
  5. 重启服务
  6. 健康检查
  7. 失败回滚

9. Rollout 与 Ops Job 的关系

约束:

  • Rollout 是分批推进对象
  • Ops Job 是单次动作对象
  • Rollout 通过一批或多批 deploy.release.* Job 落地

控制面责任:

  • 决定下一批是否生成 Job
  • 汇总 Job 结果
  • 反推 Rollout 状态
  • 决定是否暂停、继续或回滚

Node Agent 不负责:

  • 推进下一批
  • 修改 Rollout 策略
  • 修改 Release 状态

10. 页面 / Codex 共同消费约束

以下对象必须作为稳定后端 contract 存在:

  • default_rollout_gate
  • default_rollout_execution
  • launchpad_status
  • worker_rollout_preview
  • control_rollout_preview

页面只负责展示和少量交互兜底。

Codex 只负责消费后端给出的:

  • 当前是否可发
  • 建议先发哪一侧
  • 应该使用什么 mode
  • 下一步推荐动作是什么

11. Artifact Manifest Contract

Release Hub 不能只停在:

  • artifact_url
  • checksum

这只能证明“有个包”,还不能证明“这个包会把哪些服务改成什么样”。

建议把 release.metadata.manifest 固定为正式对象。

最小结构:

{
  "artifact_kind": "tarball",
  "package_name": "domaincheck-2026.04.18+bd6bcb2.tgz",
  "package_size_bytes": 186542331,
  "checksum": "sha256:...",
  "build_id": "build-20260418-001",
  "commit_sha": "bd6bcb2",
  "built_at": "2026-04-18 05:20:00",
  "included_services": [
    "domaincheck-api",
    "domaincheck-worker",
    "domaincheck-sync-agent",
    "domaincheck-node-agent"
  ],
  "required_env_keys": [
    "NODE_CODE",
    "NODE_REGION",
    "NODE_ROLE"
  ],
  "health_checks": [
    {
      "name": "api_health",
      "type": "http",
      "url": "http://127.0.0.1:8100/health"
    }
  ],
  "rollback_hint": "切回上一个 current 并重启对应服务"
}

正式要求:

  • Release 创建后,manifest 不应再被覆盖成另一份语义不同的发布物
  • Node Agent、页面、Codex 必须共用这同一份 manifest
  • 是否可发、怎么回滚、要验哪些服务,不应再散落在:
    • shell 脚本
    • 页面表单
    • 人工脑补

12. Operational Readiness Row Contract

default_rollout_gate.operational_readiness.rows[] 不应只是“几行提醒文案”,而应成为逐节点门禁对象。

最小结构:

{
  "node_code": "mainland-worker-01",
  "region": "mainland",
  "role": "worker",
  "agent_managed": true,
  "execution_mode_ready": true,
  "execution_mode": "remote-agent",
  "execution_mode_label": "Node Agent",
  "inspection_status": "healthy",
  "inspection_status_label": "已通过",
  "current_release_version": "2026.04.11+1921318",
  "desired_release_version": "2026.04.18+bd6bcb2",
  "risk_level": "low",
  "blocking_reasons": [],
  "warning_reasons": [],
  "recommended_action_code": "",
  "focus_ref": {
    "kind": "release_hub",
    "release_id": 1,
    "release_version": "2026.04.18+bd6bcb2",
    "channel": "stable",
    "rollout_id": 0,
    "rollout_code": "",
    "section": "default_rollout_gate"
  }
}

正式要求:

  • rows[] 应能直接回答:
    • 这台节点能不能进下一轮 rollout
    • 不能的话卡在哪
    • 只是 warning 还是 hard block
  • 页面、CLI、Codex 不应再从:
    • inspection
    • runtime
    • nodes 三处数据手工拼门禁结论

推荐风险分级:

  • low
  • medium
  • high
  • blocked

13. Rollout Preview Contract

真正创建 Rollout 之前,还应保留一层正式 preview而不是由页面自己预估批次和风险。

建议入口:

  • POST /api/v1/ops/releases/{id}/rollouts/preview

最小请求体:

{
  "release_id": 1,
  "target_node_codes": [
    "mainland-worker-01",
    "mainland-controller-01"
  ],
  "policy": {
    "batch_size": 1,
    "require_approval_between_batches": true,
    "rollback_on_failure": true
  },
  "execution_mode": "remote-agent"
}

最小返回体:

{
  "release": {},
  "execution_mode": "remote-agent",
  "execution_mode_label": "Node Agent",
  "target_nodes_total": 2,
  "target_node_codes": [
    "mainland-worker-01",
    "mainland-controller-01"
  ],
  "expected_batches_total": 2,
  "expected_jobs_total": 2,
  "gate": {},
  "batch_plan": [
    {
      "batch_no": 1,
      "node_codes": [
        "mainland-worker-01"
      ],
      "risk_level": "low"
    },
    {
      "batch_no": 2,
      "node_codes": [
        "mainland-controller-01"
      ],
      "risk_level": "medium"
    }
  ],
  "summary": "建议先灰度 1 台 Worker再推进 Controller。",
  "summary_text": "建议先灰度 1 台 Worker再推进 Controller。",
  "focus_ref": {
    "kind": "release_hub",
    "release_id": 1,
    "release_version": "2026.04.18+bd6bcb2",
    "channel": "stable",
    "rollout_id": 0,
    "rollout_code": "",
    "section": "rollout_preview"
  }
}

正式要求:

  • preview 是:
    • 页面发 rollout 前的统一预检
    • Codex 自动驾驶发 rollout 前的统一预检
    • CLI 批量发布前的统一预检
  • 不允许前端重新自己算:
    • 该分几批
    • 哪台应该先发
    • 哪台属于高风险

只有这样Release Hub 才是真正的发布控制面,而不是“能看版本的页面”。