chore(repo): initialize team collaboration repository
CI / Python 3.12 (push) Waiting to run
CI / Python 3.9 (push) Waiting to run

This commit is contained in:
2026-07-27 20:40:12 +08:00
commit c91a64fddb
109 changed files with 21121 additions and 0 deletions
+123
View File
@@ -0,0 +1,123 @@
# 工作流规范:SOP → 可执行状态机
> **当前状态**:这是待实现的发布与物化规范。数据库中已经保存一份符合该结构的
> 演示工作流,但 `WorkflowSpec` 完整 schema 校验、YAML 发布器与 `planner.py`
> 尚未落地;当前 API 不接受任意工作流上传。
工作流必须是**确定性的结构化配置**,不是让大模型自由生成命令(方案 §6.3、§8.1)。
AI 可以把自然语言 SOP 草拟成下面这份 YAML,但**必须过 schema 校验 + 人工发布**才能执行。
目标实现位置:`engine/planner.py`(物化)、`schemas.py::WorkflowSpec`(校验)
`workflows/fw-ab-regression.yaml`(版本化示例)。
## Schema
```yaml
key: fw-ab-regression # 全局唯一,改 key = 新工作流
name: 固件 A/B 回归
version: 3 # 每次发布 +1spec_hash 变了但 version 没变 → 拒绝发布
danger_level: high # none | low | high —— high 需要审批记录
source_sop: "客户X_固件回归SOP_v2.1(脱敏)"
params: # 运行时参数,带类型与默认值
loops: {type: int, default: 100, min: 1, max: 10000}
dut_serial: {type: string, required: true}
host: {type: string, required: true}
fw_a: {type: string, required: true} # firmware_artifact id
fw_b: {type: string, required: true}
resources: # 独占锁,PREFLIGHT 阶段获取,终态释放
- {type: dut, ref: params.dut_serial, exclusive: true}
- {type: test_host, ref: params.host, exclusive: true}
policy:
heartbeat_timeout_s: 30
max_recovery_per_loop: 3 # 单轮循环内恢复超过 3 次 → FREEZE
max_recovery_total: 20
on_data_integrity_failure: freeze # 硬编码值,写在这里只是为了显式
steps:
- key: preflight
type: precheck
adapter: safety
- key: flash-fw-a
type: command
adapter: nvme_cli
template: nvme_fw_download_commit # 只能引用已注册的签名模板
params: {firmware: "{{ params.fw_a }}", slot: 1, action: 3}
danger: high
timeout_s: 300
idempotent: false # 默认值,写出来是为了提醒:挂了不自动重跑
checkpoint: true
- key: regression-loop
type: loop
count: "{{ params.loops }}"
body:
- key: workload
type: command
adapter: fio
template: fio_seq_rw
timeout_s: 600
retry: 1
idempotent: true
- key: enumeration-check
type: device_check
adapter: nvme_cli
expect: {enumerated: true, link_speed_min: "8GT/s"}
- key: integrity-check
type: command
adapter: shell
template: sha256_readback
on_fail: freeze # 覆盖默认处置
checkpoint: true # 每轮结束落检查点
- key: report
type: report
adapter: builtin
```
## 步骤类型(MVP 六种)
| type | 语义 | 备注 |
|---|---|---|
| `command` | 执行签名命令模板 | 唯一能碰危险动作的类型 |
| `device_check` | 设备探针断言(枚举/固件版本/链路速率/SMART) | 不改变设备状态 |
| `wait` | 等待固定时长或条件 | 用于温度稳定、上电间隔 |
| `loop` | 固定次数循环,body 是步骤列表 | 支持嵌套一层 |
| `precheck` | 安全门禁 | 每个工作流的第一步都应该是它 |
| `report` | 生成报告与 Evidence Bundle | 内置适配器 |
企业版才加的:`http``parallel``subflow``approval``instrument`
这一波故意不做——`planner.py` 里遇到未知 type 直接拒绝发布,不静默跳过。
## 模板变量
只支持 `{{ params.X }}``{{ loop.index }}` 两种插值,**不支持表达式求值**。
理由:能求值就能注入。需要计算的场景写进适配器,不写进 YAML。
## 版本与 Git
工作流 YAML 进 `workflows/` 目录、进 Git。发布时控制平面记录:
```
workflows.spec 原文
workflows.spec_hash sha256(规范化后的 spec)
workflows.version 发布号
```
`spec_hash` 变了而 `version` 没变 → 拒绝发布。理由:A/B 对比的结论必须能追溯到
**具体哪一版流程**,否则"上周跑的和这周跑的是不是同一个流程"就说不清了。
## `on_fail` 的可选处置
| 值 | 行为 |
|---|---|
| `retry`(默认,受 `retry:` 次数约束) | 重试该步骤 |
| `fail_run` | 整个 Run 判 FAIL 并结束 |
| `continue` | 记失败,继续下一步(用于非关键采集步骤) |
| `freeze` | 立刻冻结现场,停止一切覆盖性动作 |
| `recover` | 进入恢复阶梯 |
数据完整性相关的步骤**只允许** `freeze`planner 校验时强制。