Files
yuanshuai c91a64fddb
CI / Python 3.12 (push) Waiting to run
CI / Python 3.9 (push) Waiting to run
chore(repo): initialize team collaboration repository
2026-07-27 20:40:12 +08:00

4.7 KiB
Raw Permalink Blame History

工作流规范: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

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 内置适配器

企业版才加的:httpparallelsubflowapprovalinstrument。 这一波故意不做——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 进入恢复阶梯

数据完整性相关的步骤只允许 freezeplanner 校验时强制。