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

19 KiB
Raw Blame History

domainCheck Ops Driver Contract

1. 目标

这份文档用于冻结 Overseas Ops Center / Codex Driver / CLI 共用的驾驶 contract。

核心原则:

  • 后端负责推荐和解释
  • 前端负责展示和触发
  • Codex 负责选择入口和上下文
  • 是否允许自动执行由后端统一门禁
  • 页面与 Codex 都不能各自再推导一套优先级

2. 入口接口

当前驾驶 contract 主要来自:

  • GET /api/v1/ops/overview
  • GET /api/v1/ops/driver-feed
  • GET /api/v1/ops/codex-brief
  • POST /api/v1/ops/driver-actions/preview
  • POST /api/v1/ops/driver-actions/resolve
  • POST /api/v1/ops/driver-actions/execute
  • POST /api/v1/ops/driver-actions/execute-resolved
  • POST /api/v1/ops/codex-actions/resolve
  • POST /api/v1/ops/codex-actions/execute

补充配套:

  • GET /api/v1/ops/playbooks
  • GET /api/v1/ops/playbook-runs
  • GET /api/v1/ops/playbook-runs/{run_code}
  • GET /api/v1/ops/playbook-runs/{run_code}/events
  • GET /api/v1/ops/activity-stream

3. Driver Recommendation

来源:

  • overview.driver_recommendations

最小字段:

{
  "key": "node-agent-dead-letter",
  "priority": "先处理 Agent 死信",
  "title": "先处理 Agent 死信",
  "summary": "当前已有节点出现死信记录,继续堆动作会放大控制面与节点现场的不一致。",
  "reason": "Node Agent 回执队列已经出现死信。",
  "level_label": "最高优先",
  "tag_type": "danger",
  "primary_label": "查看 Worker 日志",
  "secondary_label": "打开标准巡检",
  "primary_action_code": "open_worker_logs",
  "secondary_action_code": "open_diagnostics",
  "node_codes": [
    "mainland-worker-01"
  ],
  "primary_node_codes": [
    "mainland-worker-01"
  ],
  "secondary_node_codes": [
    "mainland-worker-01"
  ],
  "primary_action_payload": {},
  "secondary_action_payload": {},
  "focus_ref": {
    "kind": "ops_job",
    "job_id": 101,
    "job_code": "ops-20260418064500-a1b2c3"
  }
}

要求:

  • 推荐不只给文案
  • 必须给动作码、节点和预填 payload
  • 主次动作允许节点和 payload 不同
  • 推荐对象允许直接携带 focus_ref / primary_focus_ref / secondary_focus_ref
  • 新客户端优先用 focus_ref 做统一定位,而不是再从动作码反推页面落点

4. Priority Recommendation

来源:

  • overview.recommendation

作用:

  • 给首页顶部、CLI 摘要、Codex 首屏判断提供“当前第一优先动作”

最小字段:

{
  "source": "driver_recommendations",
  "key": "node-agent-dead-letter",
  "priority": "先处理 Agent 死信",
  "title": "先处理 Agent 死信",
  "summary": "当前已有节点出现死信记录。",
  "reason": "Node Agent 回执队列已经出现死信。",
  "primary_action_code": "open_worker_logs",
  "secondary_action_code": "open_diagnostics"
}

5. Driver Feed

来源:

  • GET /api/v1/ops/driver-feed

作用:

  • 提供比 overview 更直接给驾驶员消费的聚合结果

建议最小结构:

{
  "top_recommendation": {},
  "driver_recommendations": [],
  "runbook_sequences": [],
  "activity_focus": [],
  "automation_coverage": {}
}

推荐补充约束:

  • top_recommendation
    • 应该总是来自同一份 entries 列表,而不是额外拼一条“影子建议”
    • 这样页面、CLI、海外 Codex 在按 key 选中时才不会出现口径漂移
  • driver_recommendations
    • 普通驾驶建议,优先 executor_kind=driver_action
  • runbook_sequences
    • 标准作业路径,优先 executor_kind=runbook_sequence
  • activity_focus
    • 更偏观察与跟踪,不应伪装成“可立即执行”的驾驶动作
  • activity_focus[*]
    • 至少应保留:
      • activity_key
      • activity_kind
      • summary
      • status
      • status_label
      • occurred_at
      • focus_ref
      • source_focus_ref
      • ui_intent
    • 如果存在可落点观察入口
      • 允许补 focus_action_code=focus_activity_item
      • 但它的定位仍然是观察入口,而不是标准执行动作
  • entries[*].focus_ref
    • 是 driver-feed 的统一定位对象
    • 页面 / CLI / Codex 均应优先消费
  • entries[*].primary_focus_ref / entries[*].secondary_focus_ref
    • 是主次动作各自的稳定落点
    • 不允许调用方再根据 primary_action_code 自己猜“该跳 Release Hub、Launchpad 还是 Rollout Jobs”
  • automation_coverage
    • 是 Driver Feed 的自动化收口摘要
    • 用于统一回答:
      • 当前是否已经达到上线闸门
      • 当前还有多少动作停留在 preview-only
      • 当前后端是否已经足够接管首屏默认动作
    • 页面、CLI、Codex 不允许自行再统计一份“自动化覆盖率”

推荐最小结构:

{
  "launch_ready": false,
  "launch_status": "attention",
  "summary": "仍有 3 个驾驶动作停留在 preview-only暂未达到上线收口标准。",
  "total_actions": 12,
  "backend_handled_total": 9,
  "preview_only_total": 3,
  "ui_only_total": 0,
  "blocked_total": 0
}

其中 runbook_sequencesactivity_focus 应继续区分:

  • 这是建议动作
  • 还是固定标准作业路径
  • 还是最近值得优先处理的活动

推荐 CLI 消费顺序:

  1. 显式 entry_key
  2. top_recommendation
  3. entries[0]

这样海外单入口就能稳定实现:

  • driver-focus-preview
  • driver-focus-run

6. Codex Brief

来源:

  • GET /api/v1/ops/codex-brief

作用:

  • 不让 Codex 自己从页面文案里猜“能不能自动执行”

最小字段:

{
  "mode": "guarded_auto",
  "recommended_behavior": "confirm_then_execute",
  "summary": "当前建议先处理 Agent 死信,再进入标准巡检。",
  "automation_coverage": {
    "launch_ready": false,
    "launch_status": "attention",
    "summary": "仍有 3 个驾驶动作停留在 preview-only。"
  },
  "target": {
    "kind": "driver_action",
    "action_code": "open_worker_logs",
    "node_codes": [
      "mainland-worker-01"
    ],
    "action_payload": {}
  }
}

推荐 mode

  • safe_auto
  • guarded_auto
  • mixed
  • ui_only
  • blocked

推荐 recommended_behavior

  • auto_execute
  • confirm_then_execute
  • resolve_first
  • open_ui
  • blocked

补充约束:

  • codex-brief.automation_coverage
    • 应与 driver-feed.automation_coverage 保持同源
    • 供海外 Codex 驾驶员直接判断:
      • 是否允许默认走自动执行
      • 是否必须先预览或人工确认
      • 是否已经达到“可以上线”的自动化收口标准
  • codex-brief.activity_focus
    • 应直接透传 driver-feed.activity_focus
    • 供 Codex 在“当前没有可执行主线,但有观察焦点”时继续判断
  • codex-brief.focus
    • 优先使用 entries[0]
    • entries 为空且 activity_focus 不为空时
      • 允许回退到首条带 focus_action_codeactivity_focus
      • 这时推荐行为应偏向 open_ui
      • 不应伪装成自动执行动作

7. Driver Action Execute

来源:

  • POST /api/v1/ops/driver-actions/execute

作用:

  • 把能标准化的驾驶动作收进统一后端执行入口

最小请求体:

{
  "action_code": "run_standard_inspection",
  "node_codes": [
    "mainland-worker-01"
  ],
  "action_payload": {}
}

最小返回体:

{
  "handled": true,
  "mode": "playbook",
  "ui_intent": {
    "kind": "playbook_run_detail",
    "run_code": "run-20260418-001"
  }
}

要求:

  • 不只返回 handled / unhandled
  • 还要返回 mode
  • 还要返回 ui_intent

8. Driver Action Preview

来源:

  • POST /api/v1/ops/driver-actions/preview

作用:

  • 给 OpsCenter / CLI / Codex Driver 统一生成驾驶动作契约预览
  • 冻结 execution_chain / target_api / request_payload / 主次动作 section
  • 不再让前端自己拼请求体和执行建议

最小请求体:

{
  "source_label": "driver-feed",
  "title": "版本发布与放量",
  "summary": "当前可以进入正式发布路径。",
  "reason": "统一回到 Release / Rollout 闭环。",
  "executor_kind": "runbook_sequence",
  "sequence_key": "release_progression",
  "primary_label": "Worker 灰度",
  "secondary_label": "查看版本区",
  "secondary_action_code": "focus_release_hub",
  "requested_by": "web-ui/ops-center"
}

最小返回体:

{
  "contract_key": "ops_driver_contract",
  "contract_version": "v1",
  "contract_schema_doc_path": "docs/schemas/ops_driver_contract.md",
  "execution_chain": "ops-driver -> runbook-sequence -> resolved driver action / ui-intent",
  "focus_ref": {
    "kind": "release_hub",
    "release_id": 7,
    "section": "release_launchpad"
  },
  "primary_focus_ref": {
    "kind": "release_hub",
    "release_id": 7,
    "section": "release_launchpad",
    "mode": "worker"
  },
  "secondary_focus_ref": {
    "kind": "release_hub",
    "release_id": 7,
    "section": "release_detail"
  },
  "primary": {
    "label": "Worker 灰度",
    "action_code": "create_release_rollout_worker",
    "target_api": "/api/v1/ops/runbook/sequences/release_progression/execute",
    "target_method": "POST",
    "recommendation_label": "建议确认后执行",
    "automation_level_label": "guarded_auto",
    "risk_level_label": "high",
    "focus_ref": {
      "kind": "release_hub",
      "release_id": 7,
      "section": "release_launchpad",
      "mode": "worker"
    },
    "request_payload": {
      "secondary": false,
      "requested_by": "web-ui/ops-center",
      "node_codes": [
        "mainland-controller-01"
      ],
      "action_payload": {
        "release_id": 7,
        "focus_ref": {
          "kind": "release_hub",
          "release_id": 7,
          "section": "release_launchpad",
          "mode": "worker"
        }
      }
    }
  }
}

要求:

  • preview 必须和 execute 走同一套 action 解析与 runbook resolve 逻辑
  • primary / secondary section 必须可直接给页面抽屉和 CLI 文本渲染复用
  • request_payload 必须是真正可发送到执行接口的 body而不是页面内部临时对象
  • runbook sequence preview 必须经过后端 resolve不能由页面自己猜 action_code
  • preview 返回体必须保留:
    • focus_ref
    • primary_focus_ref
    • secondary_focus_ref
    • primary.focus_ref
    • secondary.focus_ref

8.3. Driver Action Resolve / Execute Resolved

来源:

  • POST /api/v1/ops/driver-actions/resolve
  • POST /api/v1/ops/driver-actions/execute-resolved

作用:

  • overview.driver_recommendations / driver-feed / 页面按钮 / CLI 对普通驾驶动作的门禁判断统一下沉到后端
  • 页面不再根据 preview 自己推导 直接执行 / 等确认 / 进入 UI / 阻断
  • 后端统一输出:
    • preview_request
    • preview
    • gate
    • selected_section
    • execution_result

resolve 最小请求体:

{
  "source_label": "driver-feed",
  "title": "开启关键日志回传",
  "executor_kind": "driver_action",
  "primary_action_code": "enable_log_sync_key",
  "primary_action_payload": {},
  "requested_by": "web-ui/driver-feed",
  "secondary": false,
  "confirm": false
}

resolve 最小返回体:

{
  "preview_request": {},
  "preview": {},
  "selected_section": "primary",
  "focus_ref": {
    "kind": "execution_scene",
    "scene_key": "scene.logs"
  },
  "gate": {
    "decision": "execute_now",
    "decision_label": "直接执行",
    "decision_reason": "当前动作属于 safe_auto可直接执行。",
    "will_execute": true,
    "recommendation": "auto_execute",
    "focus_ref": {
      "kind": "execution_scene",
      "scene_key": "scene.logs"
    },
    "action_code": "enable_log_sync_key",
    "target_api": "/api/v1/ops/driver-actions/execute"
  }
}

execute-resolved 约束:

  • 只有 gate.will_execute=true 才允许真正执行
  • confirmation_required 只有显式传入 confirm=true 才会放行
  • open_ui / resolve_first / blocked 必须返回非执行态,由页面或 CLI 继续展示契约
  • driver-focus-preview / driver-focus-run
    • 允许先从 driver-feed.top_recommendation 选出目标项
    • 也允许显式传入 activity_focus.key
    • 当目标来自 activity_focus
      • 应自动收口成 focus_activity_item
      • 只允许进入对应工作区,不应被当成标准执行动作
    • 再把它收口成同一份 resolve / execute-resolved 请求体
    • 不允许 CLI 再自己二次推导 gate
  • resolve 返回体必须保留:
    • preview_request.focus_ref
    • preview_request.primary_focus_ref
    • preview_request.secondary_focus_ref
    • gate.focus_ref
    • 顶层 focus_ref

8.5. Codex Action Resolve / Execute

来源:

  • POST /api/v1/ops/codex-actions/resolve
  • POST /api/v1/ops/codex-actions/execute

作用:

  • 不再让 CLI / Codex 自己从 codex-brief + preview 拼一套门禁
  • 由后端统一输出:
    • 当前选中的 selected_entry
    • 对应的 preview
    • 统一门禁结论 gate
    • 最终是否允许执行

resolve 最小请求体:

{
  "entry_key": "runbook:release_progression",
  "requested_by": "cli/ops-center/codex-focus-preview",
  "source_label": "cli/codex-focus-preview",
  "include_secondary": true,
  "confirm": false
}

resolve 最小返回体:

{
  "entry_key": "runbook:release_progression",
  "selected_entry": {},
  "preview_request": {},
  "preview": {},
  "focus_ref": {
    "kind": "release_hub",
    "release_id": 7,
    "section": "release_launchpad",
    "mode": "worker"
  },
  "gate": {
    "decision": "confirmation_required",
    "decision_label": "等待确认",
    "recommendation": "confirm_then_execute",
    "recommendation_label": "建议确认后执行",
    "will_execute": false,
    "confirm_required": true,
    "focus_ref": {
      "kind": "release_hub",
      "release_id": 7,
      "section": "release_launchpad",
      "mode": "worker"
    },
    "target_api": "/api/v1/ops/runbook/sequences/release_progression/execute",
    "target_method": "POST",
    "request_payload": {
      "secondary": false,
      "requested_by": "cli/ops-center/codex-focus-preview",
      "action_payload": {
        "release_id": 7
      }
    }
  }
}

execute 要求:

  • 必须复用 resolve 的同一套选中逻辑和门禁逻辑
  • safe_auto
    • 允许直接执行
  • guarded_auto
    • 只有 confirm=true 时允许执行
  • resolve_first / open_ui / blocked
    • 一律不得执行
  • 返回体必须保留:
    • selected_entry
    • preview_request
    • preview
    • gate
    • focus_ref
    • execution_result
    • executed

9. UI Intent

ui_intent 的职责不是让前端猜去哪,而是由后端直接声明:

  • 应打开哪个详情
  • 应聚焦哪轮 run
  • 应落到哪个发布入口

当前建议固定支持:

  • playbook_run_detail
  • playbook_run_latest_events
  • job_events
  • rollout_jobs
  • managed_node_handover
  • managed_node_edit
  • open_release_dialog
  • open_rollout_dialog
  • focus_release_hub
  • focus_ref

页面只做路由和抽屉承载,不做推荐解释。


10. Runbook Sequence

作用:

  • 表达固定标准作业路径在“此刻”的推荐下一步

最小字段:

{
  "key": "standard_inspection",
  "title": "标准巡检",
  "status": "warning",
  "status_label": "待补接管",
  "summary": "当前还没有满足标准巡检条件的节点。",
  "target_node_codes": [],
  "focus_ref": {
    "kind": "release_hub",
    "release_id": 7,
    "section": "release_launchpad"
  },
  "primary_label": "直接执行标准巡检",
  "primary_action_code": "run_standard_inspection",
  "primary_action_payload": {},
  "primary_focus_ref": {},
  "secondary_label": "打开巡检编排",
  "secondary_action_code": "open_playbook_dialog",
  "secondary_action_payload": {
    "playbook_key": "inspection.standard"
  },
  "secondary_focus_ref": {}
}

要求:

  • Runbook Sequence 是标准路径对象
  • 不是普通活动记录
  • 不是普通推荐卡
  • focus_ref
    • 表示这条标准路径整体对应的统一观察落点
  • primary_focus_ref / secondary_focus_ref
    • 表示主次动作各自应回看的稳定区域

11. Activity Stream

来源:

  • GET /api/v1/ops/activity-stream

作用:

  • 把最近异常、编排、任务、Rollout 统一压成可钻取活动流

每条 activity 最小字段:

{
  "kind": "playbook_run",
  "activity_key": "run-20260418-001",
  "status": "failed",
  "occurred_at": "2026-04-18 06:00:00",
  "summary": "标准巡检在 diagnostics.collect 步骤失败。",
  "ui_intent": {
    "kind": "playbook_run_detail",
    "run_code": "run-20260418-001"
  }
}

推荐 kind

  • playbook_run
  • ops_job
  • rollout
  • runbook_sequence

12. 单脑驾驶舱首屏约束

Ops Center 首屏不是自由拼装页面,而是 Driver Contract 的正式消费者。

首屏必须优先消费同一组 contract

  • overview.recommendation
  • driver-feed.top_recommendation
  • driver-feed.automation_coverage
  • codex-brief

首屏建议固定为三层:

  1. 驾驶结论
  2. 驾驶动作条
  3. 驾驶回执条

正式要求:

  • 驾驶结论
    • 直接展示当前第一优先动作、自动化收口状态、是否达到上线闸门
  • 驾驶动作条
    • 只放“默认下一步 / 定位下一步 / 看契约 / 复制命令 / 进入主处理面板”这类高频动作
    • 这些按钮不能自己发明新规则,必须消费已有 action_code / focus_ref / preview
  • 驾驶回执条
    • 是首屏动作后的统一反馈区
    • 用于展示:
      • 已打开哪个契约
      • 已定位哪个焦点
      • 已复制哪个命令
      • 后端动作执行成功 / 警告 / 失败
    • 页面不应再把动作结果散落在多个局部 toast 里

也就是说:

  • 首屏负责决策与触发
  • 下方详情区负责展开与下钻
  • 不允许详情区反向重写首屏推荐

13. 建议优先级顺序

当前 contract 应优先遵守:

  1. 先看异常编排
  2. 再看异常活动
  3. 再处理 Agent 死信 / 回执积压
  4. 再优先执行首个缺口节点的接入收口或接管验收
  5. 再处理现场日志回传和标准巡检
  6. 最后进入 Release / Rollout

这条顺序必须由后端维护,不应让前端或 Codex 再自行拼装。

补充约束:

  • 当后端已经把首个缺口节点收敛成 bootstrap_run / run_acceptance 时:
    • driver_feed.top_recommendation
    • codex_brief.focus
    • stack_diagnosis.next_step 都必须优先指向这一个节点和这一个动作
  • fix_managed_nodes 只能保留为兜底入口,不能再覆盖已经明确收敛的单节点恢复动作

14. 页面 / Codex / CLI 共用约束

同一条驾驶建议必须由后端一次性给出:

  • 推荐标题
  • 推荐理由
  • 主动作
  • 次动作
  • 节点范围
  • 预填参数
  • UI 落点
  • 是否允许自动执行

这样三类入口才会真正共享一套驾驶 contract

  • OpsCenter 页面
  • 海外 Codex 驾驶员
  • CLI / 运维检查脚本

并且三类入口对 recommended_behavior 的执行语义也必须一致:

  • auto_execute
    • 可直接执行
  • confirm_then_execute
    • 必须显式确认后才能执行
  • resolve_first
    • 只能先审阅和补上下文,不能直接执行
  • open_ui
    • 只能进入对应工作区,不能直接执行
  • blocked
    • 明确阻断,不能执行