13 KiB
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/releasesGET /api/v1/ops/releasesGET /api/v1/ops/releases/latestGET /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是发布可验证性的最小基线
推荐状态:
draftreadyactivearchived
3. Rollout Object
来源:
POST /api/v1/ops/releases/{id}/rolloutsGET /api/v1/ops/rollouts/{id}GET /api/v1/ops/rollouts/{id}/jobsPOST /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 在某批目标节点上的一次分批推进计划
推荐状态:
plannedrunningawaiting_approvalready_for_next_batchhaltedcompletedcompleted_with_issues
4. Default Rollout Gate
来源:
GET /api/v1/ops/overviewoverview.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_releaserelease_not_readyartifact_missingno_targetsblockedattentionready
要求:
- 首页驾驶建议
- Release 页面门禁
- Rollout 预检
- Codex 自动驾驶
必须共用这同一份 Gate。
5. Default Rollout Execution
来源:
overview.release_hub.default_rollout_executionoverview.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-agentsshcontrol-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.controldeploy.release.workerdeploy.release.custom
这三个动作必须共用:
- 同一份 Gate 判断
- 同一份 Release 版本对象
- 同一份 Rollout 编排结果
8. Artifact 不可变要求
上线前建议把 Release 供应链固定为:
- 构建产物
- 生成
checksum - 生成
manifest - 上传 artifact
- 创建 Release
- 激活 channel
- 创建 Rollout
Node Agent 侧部署链路要求:
- 下载 artifact
- 校验 checksum
- 解压到
releases/<version> - 切换
current - 重启服务
- 健康检查
- 失败回滚
9. Rollout 与 Ops Job 的关系
约束:
- Rollout 是分批推进对象
- Ops Job 是单次动作对象
- Rollout 通过一批或多批
deploy.release.*Job 落地
控制面责任:
- 决定下一批是否生成 Job
- 汇总 Job 结果
- 反推 Rollout 状态
- 决定是否暂停、继续或回滚
Node Agent 不负责:
- 推进下一批
- 修改 Rollout 策略
- 修改 Release 状态
10. 页面 / Codex 共同消费约束
以下对象必须作为稳定后端 contract 存在:
default_rollout_gatedefault_rollout_executionlaunchpad_statusworker_rollout_previewcontrol_rollout_preview
页面只负责展示和少量交互兜底。
Codex 只负责消费后端给出的:
- 当前是否可发
- 建议先发哪一侧
- 应该使用什么 mode
- 下一步推荐动作是什么
11. Artifact Manifest Contract
Release Hub 不能只停在:
artifact_urlchecksum
这只能证明“有个包”,还不能证明“这个包会把哪些服务改成什么样”。
建议把 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 三处数据手工拼门禁结论
推荐风险分级:
lowmediumhighblocked
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 才是真正的发布控制面,而不是“能看版本的页面”。