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

564 lines
12 KiB
Markdown
Raw 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 Playbook Contract
## 1. 目标
这份文档用于冻结 `playbook catalog / preview / run / events` 的正式 contract。
这层的定位不是“页面里的一个弹窗”,而是:
- 控制面的正式编排对象
- 海外 Codex 驾驶员可消费的标准作业对象
- Driver / Runbook / Release / Inspection 之间的统一中间层
核心原则:
- 一次标准编排 = 一次 `playbook run`
- 页面、CLI、Codex 必须共用同一份 `playbook` / `playbook run` 结构
- `playbook run` 只负责创建与聚合正式 `ops job`
- 不允许前端再把“标准巡检 / 接管验收 / 现场日志”退回成零散按钮逻辑
建议与 [ops_job_contract.md](/www/wwwroot/getDomain/docs/schemas/ops_job_contract.md:1) 配套阅读。
---
## 2. 当前接口面
当前已落地的主入口:
- `GET /api/v1/ops/playbooks`
- `POST /api/v1/ops/playbooks/preview`
- `POST /api/v1/ops/playbooks/execute`
- `GET /api/v1/ops/playbook-runs`
- `GET /api/v1/ops/playbook-runs/{run_code}`
- `GET /api/v1/ops/playbook-runs/{run_code}/events`
- `POST /api/v1/ops/playbook-runs/{run_code}/rerun`
- `POST /api/v1/ops/playbook-runs/{run_code}/cancel`
并且这层已经被以下入口复用:
- `driver action -> open_playbook_dialog`
- `runbook sequence -> secondary_resolution`
- `inspection`
- `activity-stream`
所以后续不应再新造第四套“标准作业对象”。
---
## 3. Playbook Catalog Object
来源:
- `GET /api/v1/ops/playbooks`
- `preview / execute` 返回体中的 `playbook`
最小字段:
```json
{
"key": "inspection.standard",
"group_key": "diagnostics",
"group_title": "标准巡检",
"title": "标准巡检",
"description": "按 健康快照 -> Worker 日志 -> 诊断包 的顺序,对目标节点做一次标准联调巡检。",
"target_scope": "node-set",
"default_execution_mode": "remote-agent",
"default_execution_mode_label": "Node Agent",
"execution_modes": [
"remote-agent",
"ssh"
],
"execution_mode_options": [
{
"value": "remote-agent",
"label": "Node Agent",
"is_default": true
},
{
"value": "ssh",
"label": "SSH",
"is_default": false
}
],
"default_auto_approve": true,
"stop_on_failure": true,
"steps": [
{
"step_key": "health",
"title": "采集健康快照",
"template_key": "health.snapshot",
"payload": {}
}
]
}
```
正式约束:
- `key`
- 是 Playbook 的稳定主键
- `group_key`
- 用于页面、CLI、Codex 做标准分组,不应用 `title`
- `execution_modes`
- 是能力白名单,不是建议文案
- `stop_on_failure`
- 是编排级行为,不是某一步骤的临时说明
---
## 4. Playbook Preview Contract
来源:
- `POST /api/v1/ops/playbooks/preview`
最小请求体:
```json
{
"playbook_key": "inspection.standard",
"node_codes": [
"mainland-worker-01"
],
"execution_mode": "remote-agent",
"auto_approve": true,
"requested_by": "web-ui"
}
```
最小返回体:
```json
{
"playbook": {},
"requested_by": "web-ui",
"execution_mode": "remote-agent",
"execution_mode_label": "Node Agent",
"auto_approve": true,
"target_nodes_total": 1,
"target_node_codes": [
"mainland-worker-01"
],
"step_count": 3,
"expected_jobs_total": 3,
"template_keys": [
"health.snapshot",
"logs.collect",
"diagnostics.collect"
],
"steps": [
{
"order": 1,
"step_key": "health",
"title": "采集健康快照",
"template_key": "health.snapshot",
"action": "health.snapshot",
"payload": {},
"execution_mode": "remote-agent",
"execution_mode_label": "Node Agent",
"auto_approve": true,
"target_nodes_total": 1,
"expected_jobs": 1
}
]
}
```
预览阶段必须回答:
- 最终执行方式是什么
- 总共会展开多少步
- 每步会展开成什么模板
- 总共会生成多少个 `ops job`
这样页面、CLI、Codex 才能在执行前看见“这次会做什么”。
---
## 5. Playbook Run Object
来源:
- `GET /api/v1/ops/playbook-runs`
- `GET /api/v1/ops/playbook-runs/{run_code}`
- `POST /api/v1/ops/playbooks/execute`
最小字段:
```json
{
"run_code": "playbook-20260418-001",
"playbook_key": "inspection.standard",
"playbook_title": "标准巡检",
"group_key": "diagnostics",
"group_title": "标准巡检",
"requested_by": "web-ui",
"execution_mode": "remote-agent",
"execution_mode_label": "Node Agent",
"stop_on_failure": true,
"step_count": 3,
"expected_jobs_total": 3,
"target_nodes_total": 1,
"target_node_codes": [
"mainland-worker-01"
],
"created_at": "2026-04-18 06:30:00",
"updated_at": "2026-04-18 06:31:10",
"status": "running",
"status_label": "收口中",
"status_counts": {
"queued": 1,
"running": 1,
"success": 1
},
"jobs_total": 3,
"success_jobs_total": 1,
"terminal_jobs_total": 1,
"completion_percent": 33.3,
"steps_total": 3,
"steps_success": 1,
"steps_running": 1,
"steps_problem": 0,
"steps_terminal": 1,
"focus_level": "warning",
"focus_step_key": "worker_logs",
"focus_step_title": "收集 Worker 日志",
"focus_summary": "收集 Worker 日志 当前仍在执行,先等待回执或检查对应节点事件流。",
"summary": "收集 Worker 日志 当前仍在执行,先等待回执或检查对应节点事件流。",
"summary_text": "收集 Worker 日志 当前仍在执行,先等待回执或检查对应节点事件流。",
"focus_ref": {
"kind": "playbook_run",
"run_code": "playbook-20260418-001",
"playbook_key": "inspection.standard",
"group_key": "diagnostics",
"focus_step_key": "worker_logs",
"focus_step_title": "收集 Worker 日志",
"event_key": "",
"node_code": ""
},
"problem_steps": [],
"active_steps": [],
"latest_job": {},
"steps": []
}
```
正式定义:
> `playbook run` 是一轮标准编排在控制面的聚合对象,不是某一条单独任务。
也就是说:
- `ops job` 是执行颗粒度
- `playbook run` 是观察、重跑、取消、钻取的编排颗粒度
---
## 6. Playbook Step Object
`playbook run.steps[]` 的最小结构:
```json
{
"step_key": "worker_logs",
"title": "收集 Worker 日志",
"template_key": "logs.collect",
"order": 2,
"jobs_total": 1,
"nodes_total": 1,
"target_node_codes": [
"mainland-worker-01"
],
"status_counts": {
"running": 1
},
"terminal_jobs_total": 0,
"success_jobs_total": 0,
"status": "running",
"status_label": "收口中",
"completion_percent": 0.0,
"summary": "收集 Worker 日志 当前处于执行中,可继续观察该步骤事件。",
"summary_text": "收集 Worker 日志 当前处于执行中,可继续观察该步骤事件。",
"focus_ref": {
"kind": "playbook_run",
"run_code": "playbook-20260418-001",
"playbook_key": "inspection.standard",
"group_key": "diagnostics",
"focus_step_key": "worker_logs",
"focus_step_title": "收集 Worker 日志",
"event_key": "",
"node_code": ""
},
"latest_job": {}
}
```
推荐 step 状态:
- `queued`
- `running`
- `success`
- `attention`
规则:
- 只要该步骤出现失败、阻断、取消等终态问题,应收口为 `attention`
- 页面与 Codex 都应优先盯 `problem_steps / active_steps`,而不是自己遍历所有子任务推断
---
## 7. Playbook Event Stream
来源:
- `GET /api/v1/ops/playbook-runs/{run_code}/events`
最小返回体:
```json
{
"run_code": "playbook-20260418-001",
"playbook_run": {},
"events": [
{
"job_id": 123,
"job_code": "ops-20260418-123",
"run_code": "playbook-20260418-001",
"job_status": "running",
"job_status_label": "收口中",
"action": "logs.collect",
"target_node_code": "mainland-worker-01",
"step_key": "worker_logs",
"step_title": "收集 Worker 日志",
"event_type": "job_running",
"level": "info",
"level_label": "信息",
"message": "开始收集 Worker 日志",
"summary": "开始收集 Worker 日志",
"summary_text": "开始收集 Worker 日志",
"payload": {},
"event_key": "job-event:1001",
"occurred_at": "2026-04-18 06:31:00",
"focus_ref": {
"kind": "playbook_run",
"run_code": "playbook-20260418-001",
"playbook_key": "inspection.standard",
"group_key": "diagnostics",
"focus_step_key": "worker_logs",
"focus_step_title": "收集 Worker 日志",
"event_key": "job-event:1001",
"node_code": "mainland-worker-01"
},
"created_at": "2026-04-18 06:31:00"
}
],
"summary": {
"total": 1,
"returned_total": 1,
"available_step_counts": {
"worker_logs": 1
},
"available_node_counts": {
"mainland-worker-01": 1
},
"level_counts": {
"info": 1
},
"event_type_counts": {
"job_running": 1
},
"job_status_counts": {
"running": 1
},
"latest_at": "2026-04-18 06:31:00",
"filters": {
"step_key": "",
"node_code": "",
"limit": 80
}
}
}
```
这层必须支持:
-`step_key` 过滤
-`node_code` 过滤
- 快速看到最近活动时间
否则 `playbook run` 只能看总览,不能真正钻取。
---
## 8. 正式 Playbook Key 语义
当前最值得冻结成正式对象的 key
### 8.1 `onboarding.bootstrap`
定位:
- 生成节点接入工单
执行方式:
-`control-plane`
正式语义:
- 不直接接管节点
- 只创建标准接入方案对象
### 8.2 `onboarding.acceptance`
定位:
- 新节点接管后标准验收
当前标准步骤:
1. `health.snapshot`
2. `service.status(node-agent)`
3. `logs.collect(node-agent)`
4. `service.status(worker)`
5. `logs.collect(worker)`
### 8.3 `inspection.standard`
定位:
- 标准巡检
当前标准步骤:
1. `health.snapshot`
2. `logs.collect(worker)`
3. `diagnostics.collect`
正式要求:
- 这是 release / rollout 之前最核心的健康观察面
### 8.4 `scene.logs.key`
定位:
- 关键现场日志样本
正式要求:
- 默认比 `scene.logs.full` 更轻
- 适合先看现场,再决定是否升级取证
### 8.5 `scene.logs.full`
定位:
- 全量现场取证
正式要求:
- 应明确比 `scene.logs.key` 更重
- 默认应同时补诊断包
### 8.6 `scene.diagnostics`
定位:
- 轻量诊断包
正式要求:
- 适合作为参与节点的常规取证动作
---
## 9. 执行模式 Contract
推荐模式:
- `remote-agent`
- `ssh`
- `control-plane`
正式约束:
- `remote-agent`
- 正式日常运维默认模式
- `ssh`
- 仅用于首发接管与应急救援
- `control-plane`
- 只适合控制面本地对象生成或极少量控制面动作
页面、CLI、Codex 不能自己发明第四种临时模式。
---
## 10. Playbook Run 状态机
推荐状态:
- `queued`
- `running`
- `success`
- `attention`
含义:
- `queued`
- 子任务刚创建,尚未出现有效执行推进
- `running`
- 已有子任务进入 `dispatching / running / awaiting_approval`
- `success`
- 全部子任务收口成功
- `attention`
- 任一步骤出现失败、阻断、取消或部分成功,需要人工关注
正式规则:
- 页面上的“标准巡检状态”
- `activity-stream` 中的 playbook run 摘要
- Driver / Codex 的推荐动作
都必须共用这一套状态语义。
---
## 11. 与 Driver / Runbook / Release 的关系
正式收口规则:
- Driver 不直接“模拟巡检”
- 应优先跳转或创建 `playbook run`
- Runbook Sequence 不直接展开 shell
- 应优先收口到 `driver action``playbook`
- Release / Rollout 不自己维护另一套巡检摘要
- 应优先消费 `inspection.standard` 的最近结果
也就是说:
- `scene` 是现场观察对象
- `inspection` 是标准健康对象
- `release / rollout` 是发布对象
三者不能再各自维护不同的“日志 / 诊断 / 巡检”定义。
---
## 12. 正式要求
后续继续演进时,必须保持:
1. `playbook catalog`
- 是稳定 contract而不是页面枚举
2. `playbook preview`
- 是执行前的唯一结构化预览面
3. `playbook run`
- 是页面、CLI、Codex 共同观察的一轮编排对象
4. `playbook events`
- 是整轮编排的钻取视角
5. 接管验收、标准巡检、现场观察
- 优先都收进 `playbook`
这样这套编排才能成为真正的正式平台能力,而不是一组“看起来像流程”的按钮。