# 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` 最小字段: ```json { "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 首屏判断提供“当前第一优先动作” 最小字段: ```json { "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` 更直接给驾驶员消费的聚合结果 建议最小结构: ```json { "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 不允许自行再统计一份“自动化覆盖率” 推荐最小结构: ```json { "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_sequences` 与 `activity_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 自己从页面文案里猜“能不能自动执行” 最小字段: ```json { "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_code` 的 `activity_focus` - 这时推荐行为应偏向 `open_ui` - 不应伪装成自动执行动作 --- ## 7. Driver Action Execute 来源: - `POST /api/v1/ops/driver-actions/execute` 作用: - 把能标准化的驾驶动作收进统一后端执行入口 最小请求体: ```json { "action_code": "run_standard_inspection", "node_codes": [ "mainland-worker-01" ], "action_payload": {} } ``` 最小返回体: ```json { "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` - 不再让前端自己拼请求体和执行建议 最小请求体: ```json { "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" } ``` 最小返回体: ```json { "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` 最小请求体: ```json { "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` 最小返回体: ```json { "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` 最小请求体: ```json { "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` 最小返回体: ```json { "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 作用: - 表达固定标准作业路径在“此刻”的推荐下一步 最小字段: ```json { "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 最小字段: ```json { "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` - 明确阻断,不能执行