feat: add ops center and node onboarding flow

This commit is contained in:
Your Name
2026-04-18 23:52:51 +08:00
parent 246838ae4c
commit b9c29481b5
142 changed files with 89727 additions and 186 deletions

View File

@@ -0,0 +1,797 @@
# 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`
- 明确阻断,不能执行