# Workflow Runner

> 十步循环轻量编排器，协调 Phase Skills 执行，支持灵活组合。 使用场景："执行 quick-fix 工作流"、"运行 [Phase B, Phase C]"、自定义 Phase 组合

- Skill: `10cg/workflow-runner` (Agent Skill, multi-file: 10 files)
- Install (CLI): `npx skillmds@latest add 10cg/workflow-runner`
- Raw SKILL.md: https://api.skillmd.com/api/skills/10cg/workflow-runner/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Productivity
- Author: 10cg (https://skillmd.com/u/10cg)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/10cg/workflow-runner

---


# Workflow Runner v2.3 (轻量编排器)

> **版本**: 2.3.0 | **架构**: Phase-Based
> **更新**: 2026-05-10 — `wait_recoverable` 错误类型 + `gate_state` workflow-state 扩展 (#60 D2)
> **类型**: 编排器 (调用 Phase Skills)
> **更新**: 2026-02-05 - 添加 A.0.5 头脑风暴步骤集成

## 快速开始

### 我应该使用这个 Skill 吗？

**使用场景**:
- 接收 state-scanner 的工作流推荐
- 需要执行多个 Phase 的组合工作流
- 使用预置工作流模板

**不使用场景**:
- 只需执行单个 Phase → 直接使用对应 Phase Skill
- 需要状态感知和推荐 → 先使用 state-scanner
- 探索性开发 → 逐步手动调用

### 入口选择

```
用户任务
    │
    ├─ 需要状态感知/推荐? ──Yes──▶ state-scanner ──▶ workflow-runner
    │
    └─ 已知要执行的工作流? ──Yes──▶ workflow-runner (直接)
```

---

## 配置 (config-loader)

执行前读取 `.aria/config.json`，缺失则使用默认值。参见 [config-loader](../config-loader/SKILL.md)。

| 字段 | 默认值 | 说明 |
|------|--------|------|
| `workflow.auto_proceed` | `false` | Phase 间自动推进 (需用户在 config 中显式启用) |

---

## 架构概览

### v2.0 vs v1.0

| 特性 | v1.0 | v2.0 |
|------|------|------|
| 执行单元 | 单步骤 (A.1, B.2...) | Phase (A, B, C, D) |
| 跳过逻辑 | 集中在 workflow-runner | 委托给各 Phase Skill |
| 上下文 | 手动传递 | 自动传递 context_for_next |
| 组合方式 | 步骤列表 | Phase 组合 |
| 复杂度 | 高 (管理10步) | 低 (管理4个Phase) |

### Phase Skills 架构

```
workflow-runner (编排器)
     │
     ├──▶ A.0.5 brainstorm (可选) ← 新增
     │         └── problem/requirements/technical 模式
     │
     ├──▶ phase-a-planner (A.1-A.3)
     │         └── spec-drafter (内置 brainstorm), task-planner
     │
     ├──▶ phase-b-developer (B.1-B.3)
     │         └── branch-manager, test-verifier, arch-update
     │
     ├──▶ phase-c-integrator (C.1-C.2)
     │         └── commit-msg-generator, branch-manager
     │
     └──▶ phase-d-closer (D.1-D.2)
               └── progress-updater, openspec:archive
```

---

## 预置工作流

| 工作流 | Phases | 适用场景 |
|--------|--------|---------|
| `quick-fix` | B → C | 简单 Bug 修复 |
| `feature-dev` | A → B → C | 功能开发 |
| `doc-update` | B.3 → C | 文档更新 |
| `full-cycle` | A → B → C → D | 完整开发周期 |
| `commit-only` | C.1 | 仅提交 |

详见 [WORKFLOWS.md](./WORKFLOWS.md)

---

## 执行流程

### 输入格式

```yaml
# 预置工作流
workflow: quick-fix

# 或 Phase 组合
phases: [B, C]

# 或自定义步骤
steps: [B.2, C.1]

# 可选配置
config:
  dry_run: false
  context:
    module: "mobile"
    spec_id: "add-auth-feature"
```

### 执行过程

```yaml
1. 解析工作流:
   - 预置模板 → 转换为 Phase 列表
   - Phase 组合 → 直接使用
   - 步骤列表 → 映射到 Phase

2. 上下文准备:
   - 接收 state-scanner 传递的上下文
   - 或读取当前项目状态

3. A.0.5 头脑风暴检查 (v2.2.0 新增):
   - 检测工作流包含 Phase A
   - 检查 state-scanner 推荐中是否包含 brainstorm 模式
   - 如果推荐 → 在 Phase A 前执行 brainstorm
   - 传递决策记录到 spec-drafter

4. Pre-Hook 检查 (v2.1.0):
   - 检测是否包含 Phase B
   - 如果包含 → 启用 TDD 主会话 Hook (方案 B)
   - 记录 tdd_session_id

5. Phase 顺序执行:
   - 调用对应 Phase Skill
   - 传递 context_for_next 到下一 Phase
   - 收集执行结果
   - 每个 Phase 完成后更新 workflow state (见 Workflow State Persistence)
   - 如启用 auto-proceed 模式，Phase 完成后自动推进到下一 Phase (Gate 暂停除外)。详见 [references/auto-proceed.md](./references/auto-proceed.md)

6. Post-Hook 清理 (v2.1.0):
   - 检测 Phase B 完成
   - 可选: 保持或关闭 TDD Hook

7. 结果汇总:
   - 生成执行报告
   - 返回最终状态
```

---

## 上下文传递

### 自动传递机制

```yaml
Phase A 输出:
  context_for_next:
    spec_id: "add-auth-feature"
    task_list: [TASK-001, ...]
    assigned_agents: {...}
           │
           ▼
Phase B 接收 + 输出:
  context_for_next:
    branch_name: "feature/add-auth"
    test_results: { passed: true, coverage: 87.5 }
           │
           ▼
Phase C 接收 + 输出:
  context_for_next:
    commit_sha: "abc1234"
    pr_url: "https://..."
           │
           ▼
Phase D 接收:
  # 使用所有上下文完成收尾
```

### 上下文合并

```yaml
context_merge:
  strategy: deep_merge
  priority: later_wins  # 后续 Phase 输出覆盖前面的
```

---

## Workflow State Persistence

工作流执行期间，通过 `.aria/workflow-state.json` 跟踪状态，支持中断恢复和进度可视化。

Schema 详见 [references/workflow-state-schema.md](./references/workflow-state-schema.md)

### State Creation

工作流启动时，创建初始状态文件:

1. 确保 `.aria/` 目录存在 (`mkdir -p .aria`)
2. 生成 `session_id` (格式: `sess-YYYYMMDD-XXXXXX`，X 为随机十六进制)
3. 写入初始状态:
   - `session.workflow_name`: 当前工作流名称
   - `session.phases`: 计划执行的 Phase 列表
   - `session.status`: `"running"`
   - `git_context.branch`, `git_context.start_commit`: 当前分支和 HEAD SHA
4. **原子写入**: 先写到 `.aria/workflow-state.json.tmp`，再 `rename` 覆盖正式文件

### State Updates

每个 Phase 完成后立即更新:

- `execution.current_phase` / `current_step`: 推进到下一 Phase
- `execution.phase_results.<phase>`: 记录该 Phase 输出 (status, context_for_next)
- `session.last_active_at`: 更新为当前时间戳
- `integrity.state_hash`: 重新计算 (SHA-256 of content without integrity block)

### Gate State

通过质量门时记录:

- **Gate 1** (Spec 审批): 设置 `gates.gate1_spec_approved: true`
- **Gate 2** (合并主干): 设置 `gates.gate2_merge_main: true`

Gate 强制执行逻辑、手动/自动模式切换、失败恢复详见 [references/gate-enforcement.md](./references/gate-enforcement.md)

### Pre-Action Gate State (v2.3.0+)

> 新增于 v2.3.0 — 支持 `wait_recoverable` 错误类型 (#60 phase-c-integrator C.2.4 pre-merge gate)。

`gate_state` 顶级 block 跟踪当前活跃的 pre-action gate (currently only `pre_merge`,但 schema 通用化为未来 `pre_release` / `pre_deploy` 预留扩展):

```json
{
  "gate_state": {
    "name": "pre_merge",
    "status": "waiting | green | fail",
    "started_at": "ISO 8601",
    "retry_count": 0,
    "next_check_at": "ISO 8601",
    "in_flight_runs": [
      {"run_id": 3161, "branch": "main", "started_at": "ISO 8601", "elapsed_seconds": 459}
    ],
    "primitive_used": "aether-ci-cli",
    "raw_message": "",
    "no_run_observations": 0
  }
}
```

`no_run_observations` (v1.66.5+ #152): 本 episode 连续带 `gate_error.kind == "no-run-for-branch"` 的观测次数,含初次;某轮非该 kind → 归零。

完整 schema 见 [references/workflow-state-schema.md §1.1.gate_state](./references/workflow-state-schema.md)。Schema migration `format_version 1.0 → 1.1` 见 §8.3 默认 `gate_state: null`。

**Defensive access**: 所有读 `gate_state` 的代码必须用 `state.get("gate_state") or {}` 而非 `state["gate_state"]`,防 v1.0 state 文件 KeyError。

### State Cleanup

工作流结束时的清理策略:

| 场景 | 动作 |
|------|------|
| 正常完成 | 删除 `.aria/workflow-state.json` |
| 用户放弃 | 删除 `.aria/workflow-state.json` |
| 执行失败 | 保留文件，设置 `session.status: "failed"` (供恢复使用) |

---

## 错误处理

### Phase 级别

```yaml
on_phase_error:
  action: stop          # stop | continue | rollback
  report: true
  suggestion: "查看 Phase X 错误详情"
```

### 可恢复策略

```yaml
recovery:
  Phase_B_failed:
    - 保留已创建的分支
    - 报告测试失败详情
    - 建议: "修复测试后从 Phase B 重新开始"

  Phase_C_failed:
    - 回滚 git commit (如果已执行)
    - 建议: "检查提交消息或 hook 错误"
```

### `wait_recoverable` 错误类型 (v2.3.0+)

> 新增于 v2.3.0 — 修复 Forgejo Issue #60 phase-c-integrator C.2.4 pre-merge gate。
> "等待外部 CI 完成" 是协作正常态,**不**应当作 fatal error 处理。

**触发场景**:
- phase-c-integrator C.2.4 返回 `verdict=wait` (main 分支有 in-flight CI 或 PR CI pending)
- phase-c-integrator C.2.4 `pr_ci_status="not_found"` (远端零 run,产 `gate_error.kind="no-run-for-branch"`) → 同样归为 `verdict=wait` (v1.66.5+ #152)
- 未来扩展: 任何 pre-action gate 返回 wait 状态 (eg pre_release / pre_deploy)

**配置**:

```yaml
on_phase_error:
  wait_recoverable:
    triggered_by:
      - source: "phase-c-integrator"
        sub_step: "C.2.4"
        verdict: "wait"
    behavior:
      - log: "main 分支有 in-flight CI,等待 X 完成"  # gate_error.kind=no-run-for-branch 态改用 gate_error.message (v1.66.5+ #152)
      - persist: workflow-state.json 写 gate_state block
      - sleep: wait_check_intervals[retry_count] (默认指数退避)
      - re-invoke: phase-c-integrator C.2.4 重新检查
```

**Exit conditions** (优先级 first-match-wins, R2 patch CR-4;v1.66.5+ #152 扩为五条,新增 2.5):
1. **user Ctrl-C** → 转 manual mode (workflow-state 标 `session.status: suspended`,允许 resume) [最高]
2. **retry_count > max OR elapsed > wait_timeout_seconds** → user prompt (continue / abort);`continue` ⇒ CLI `reset --retry-count --observations` (两者归零,且 `reset --retry-count` 同时置 `started_at=now` — exit 2 实际只由 elapsed 触发,不重置 `started_at` 则 continue 后每 30s 再弹)
2.5 **(v1.66.5+ #152 新增)** `out.gate_error.kind == "no-run-for-branch"` AND `record.should_prompt` → **no-run prompt**(定义见 [phase-c-integrator SKILL.md §C.2.4 步骤 6](../phase-c-integrator/SKILL.md) 处方段,本文只引用不复制;措辞要点: `🔴 C.2.4: <gate_error.message 原文>。已连续 <record.no_run_observations> 次观测到零 run (~<record.elapsed_seconds>s)。` 处方择一由用户执行 — (a) dispatch 命令行已由 gate 渲染进 message,AI 只填 `<owner>/<repo>`,message 无此行则 (a) 不出现 / (b) 推一个碰 CI 触发路径的实质 commit (若 workflow 有 `branches` 过滤且不含本分支则无效) / (c) continue / abort);`continue` ⇒ CLI `reset --observations` 回 loop (retry_count/started_at 继续累计,exit 2 上界不变);`abort` ⇒ verdict=fail 语义(session failed,保留 gate_state 给 audit trail)
3. **verdict=fail** → 转为 stop (fatal) [不变]
4. **verdict=green** → 继续 merge (正常路径) [最低,不变]

> 时间轴: 默认阈值 3 + intervals `[30,60,120,…]` ⇒ 首次 gate 后 ~90s 交人 (非等满 1800s);continue 后第二次 prompt ≈810s。

**实施步骤**:

```
当 phase-c-integrator C.2.4 返回 verdict=wait:
  1. 读 .aria/config.json 加载 phase_c_integrator.pre_merge_gate.* 配置
  2. 首个 wait verdict → 创建 gate_state 也经 CLI record (同 3c' 全旗标; is_first ⇒ retry_count=0, obs=1 若带 kind)  # 非 AI 手写 JSON
     所有 CLI 调用显式传 --state-file <主仓根绝对路径>/.aria/workflow-state.json (helper 默认相对 cwd, 子模块 cwd 下会静默另起 state + 分区)
  3. 进入 polling loop:
     a. 计算本轮 sleep 时长: wait_check_intervals[min(retry_count, len-1)]
     b. polling sleep chunk 模式 (CR-5): sleep 拆分 5s 块
        - 每块结束 check `.aria/.workflow-interrupt` flag file
        - flag 存在 → 立即 break,转 suspended
     c. sleep 结束 → 重调 phase-c-integrator C.2.4 gate → 得 out
     c'. record = python3 "${CLAUDE_PLUGIN_ROOT:-aria}/skills/workflow-runner/scripts/gate_state_helper.py" record --state-file <主仓 .aria/workflow-state.json 绝对路径> --name pre_merge --verdict out.verdict --intervals <json(cfg.wait_check_intervals)> --in-flight-runs <json(out.in_flight_runs)> --raw-message <out.raw_message> --source production [--gate-error-kind out.gate_error.kind --threshold out.gate_error.prompt_after_observations]
        # 两旗标仅 out.gate_error.kind == "no-run-for-branch" 时传 (fail 类 kind 无 threshold 键); in_flight_runs / raw_message 必须透传; 先自增, 后求值
     d. 按 exit conditions 处理 (输入 = out + record); CLI 退出码 2 → surface 错误 → 直接 abort (终止分支; 不再调 reset — reset 同样会退 2), 禁止回退手写 JSON
  4. 退出 polling 后:
     - verdict=green → 调 branch-manager merge,清理 gate_state
     - verdict=fail → workflow-state.session.status=failed,保留 gate_state 给 audit trail
     - timeout → user prompt;continue → reset retry_count + 继续;abort → stop
     - Ctrl-C → workflow-state.session.status=suspended,保留 gate_state 给 resume
```

### Ctrl-C 检测机制 (v2.3.0+)

> CR-5 R2 patch — workflow-runner 现无 signal handler 设计,采用 polling sleep chunk 模式

**Flag-file lifecycle** (R2-CR-B inline patch):
- **创建**: workflow-runner 顶层 SIGINT handler 收到中断时 atomic write `.aria/.workflow-interrupt` (open-O_CREAT-O_EXCL + tmp+rename)
- **检查**: polling sleep chunk 每块结束后 `os.path.exists(.aria/.workflow-interrupt)`
- **清理时机** (3 处):
  - workflow-runner 启动入口 (resume 或 fresh): 无条件清理 stale flag
  - 进入 manual mode / suspended 状态后: **保留** flag (待 user explicit clear / resume)
  - user resume workflow 时: 清理 flag (resume 是新意图,不继承 prior interrupt)
- **Ownership**: flag 文件只属当前 workflow-runner pid;多 workflow-runner 并发不允许 (沿用现有 workflow-state lock 约定)

**Chunk 大小 trade-off**: `phase_c_integrator.pre_merge_gate.poll_chunk_seconds` 默认 5s;过小耗 CPU,过大 Ctrl-C 响应慢。

### Resume 语义 (v2.3.0+)

> CR-6 + BA-5 R2 patch — workflow 中断后 resume 时正确处理 gate_state

`workflow-state.json` 含 `gate_state.status == waiting` AND `phase_results.C.2.action.pr_number != null` (PR 已创建) 时:

1. **resume 入口先清理 stale flag**: `rm -f .aria/.workflow-interrupt` (R2-CR-B,resume 是新意图)
2. **判定 next_check_at 是否过期** (R2 inline patch QA-12 — clock 源):
   - `next_check_at` 持久化为 ISO 8601 wall clock (跨进程可读)
   - elapsed 用 `time.monotonic()` 防 DST/系统时钟漂移
   - 已过期 (`now >= next_check_at`) → 立即重新调 C.2.4 gate
   - 未过期 → 等待至 `next_check_at` 后再调
3. **gate verdict 处理**:
   - `green` → **跳过** C.2 push/create-PR (已完成,PR_NUMBER 已持久化),直接调 branch-manager merge call (idempotent — 若 PR 已 merged 则 branch-manager 报告 success 不重复操作)
   - `wait` → 增量更新 `gate_state.retry_count` + `next_check_at`(若 `gate_error.kind=no-run-for-branch` 则同步累计 `no_run_observations`),继续 polling
   - `fail` → workflow report 含 PR_NUMBER + 失败 verdict,转 stop
4. **不重跑 Phase C 整段**,只 re-run gate + merge call (避免重复推送 / 重复创建 PR)

---

## 输出格式

执行报告示例:

```
╔══════════════════════════════════════════════════════════════╗
║              WORKFLOW EXECUTION REPORT                        ║
╚══════════════════════════════════════════════════════════════╝

Workflow: feature-dev
Duration: 2m 15s
Status: SUCCESS

───────────────────────────────────────────────────────────────
PHASE RESULTS:

  Phase A (规划) - 45s
     spec_id: add-auth-feature
     tasks: 5

  Phase B (开发) - 60s
     branch: feature/add-auth
     tests: 15/15 passed (87.5% coverage)

  Phase C (集成) - 30s
     commit: abc1234
     pr: #123
───────────────────────────────────────────────────────────────
```

完整输出格式（含执行计划、使用示例等）详见 [references/output-formats.md](./references/output-formats.md)

---

## TDD 双保险 Pre-Hook (v2.1.0)

Phase B 执行时应用 TDD pre-hook 策略，在工作流级别自动启用 TDD 双保险机制：
- **方案 A**: phase-b-developer 传递 TDD 配置给 Fresh Subagent
- **方案 B**: workflow-runner 通过 Pre-Hook 启用主会话 TDD Hook

详见 [references/tdd-pre-hook.md](./references/tdd-pre-hook.md)

---

## 与 state-scanner 的协作

### 推荐流程

```
state-scanner
    │
    │ 收集状态 + 分析 + 推荐
    │
    ▼
recommendation:
  workflow: quick-fix
  context:
    phase_cycle: "Phase4-Cycle9"
    module: "mobile"
    changed_files: [...]
    │
    │ 用户确认
    │
    ▼
workflow-runner
    │
    │ 执行工作流
    │
    ▼
result
```

### 上下文继承

```yaml
# state-scanner 传递
context:
  phase_cycle: "Phase4-Cycle9"
  module: "mobile"
  changed_files: [...]

# workflow-runner 使用
→ 传递给 Phase A/B/C/D
→ 用于生成提交消息
→ 更新 UPM 进度
```

---

## 相关文档

- [WORKFLOWS.md](./WORKFLOWS.md) - 工作流详细定义
- [MIGRATION.md](./MIGRATION.md) - v1.0 → v2.0 迁移指南
- [references/tdd-pre-hook.md](./references/tdd-pre-hook.md) - TDD 双保险详细策略
- [references/output-formats.md](./references/output-formats.md) - 完整输出格式定义
- [references/workflow-state-schema.md](./references/workflow-state-schema.md) - 工作流状态 Schema
- [references/auto-proceed.md](./references/auto-proceed.md) - Auto-Proceed 模式规范
- [references/gate-enforcement.md](./references/gate-enforcement.md) - Gate 强制执行、手动回退、失败恢复
- [brainstorm](../brainstorm/SKILL.md) - 头脑风暴引擎 (新增 A.0.5)
- [state-scanner](../state-scanner/SKILL.md) - 状态感知与推荐
- [phase-a-planner](../phase-a-planner/SKILL.md) - Phase A
- [phase-b-developer](../phase-b-developer/SKILL.md) - Phase B
- [phase-c-integrator](../phase-c-integrator/SKILL.md) - Phase C
- [phase-d-closer](../phase-d-closer/SKILL.md) - Phase D
- [tdd-enforcer](../tdd-enforcer/SKILL.md) - TDD 强制执行

---

**最后更新**: 2026-03-16
**Skill版本**: 2.3.0

