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

798 lines
19 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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`
- 明确阻断,不能执行