---
name: execution-sdd-orchestrator
description: SDD 编排技能。将 controller.ts 的 implement→review→fix 循环转化为宿主 Agent 可执行的指令。当执行 specpow apply 或用户要求实现变更时使用。
version: 1.0.0
trigger: on-demand
---

# SDD 编排技能

当执行 `specpow apply` 或用户要求实现变更时，按以下流程执行。

## 前置条件

- 变更提案已完成：`.specpow/changes/{change}/` 存在
- 任务清单已生成：`.specpow/changes/{change}/task-manifest.json`（Host-Driven 模式由 `apply.ts` 生成）
- Ledger 位置：`.specpow/changes/{change}/sdd/progress.md`

## 执行流程

### 步骤 1：初始化

1. 读取 Ledger（`progress.md`），检查是否有已完成的任务（断点续跑）
2. 读取任务清单：`.specpow/changes/{change}/task-manifest.json`（包含增强描述和 specConstraints）
3. 记录 BASE commit：`git rev-parse HEAD`

### 步骤 2：逐任务执行

对每个未完成任务：

#### 2a. 创建 Brief

读取任务信息，创建 brief 文件：
- **路径**：`.specpow/changes/{change}/sdd/task-{N}-brief.md`
- **内容**：
  ```markdown
  # Task {N}: {title}

  ## 描述
  {description}

  ## 涉及文件
  {files list}

  ## Spec 约束
  {spec constraints from specs/ directory}

  ## 输出要求
  完成后写 Report JSON 到：`.specpow/changes/{change}/sdd/task-{N}-report.md`
  ```

#### 2b. 派发实现者子代理

使用宿主原生 subagent 工具派发：
- **Prompt**：读取 brief 文件 + TDD 指令 + spec 约束
- **模型选择**（参考，可根据实际情况调整）：
  - ≤2 文件 + 完整 spec → `cheap`（haiku）
  - 多文件协调 → `standard`（sonnet）
  - 需要架构判断 → `capable`（opus）
- **指令**：
  1. 读取 brief 文件
  2. TDD 流程：RED → GREEN → REFACTOR
  3. 遵守 spec 约束
  4. 完成后写 Report JSON 到 reportPath

#### 2c. 检查 Report

读取 `.specpow/changes/{change}/sdd/task-{N}-report.md`，解析 JSON：
```json
{
  "status": "done|blocked|in_progress|done_with_concerns|needs_context",
  "commits": ["sha1", "sha2"],
  "testSummary": "X tests passed",
  "concerns": "any issues or null",
  "fixReport": "修复说明（仅 fix 轮次）"
}
```

- `status === 'blocked'` → 记录到 Ledger：`Task {N}: BLOCKED — {concerns}`，跳过此任务
- `status === 'done'` → 继续审查

#### 2d. 生成审查包

运行 `git diff` 生成变更摘要：
```bash
BASE_COMMIT={recorded base commit}
HEAD_COMMIT=$(git rev-parse HEAD)
git diff ${BASE_COMMIT}..${HEAD_COMMIT} > .specpow/changes/{change}/sdd/review-package.md
```

#### 2e. 派发审查者子代理

使用宿主原生 subagent 工具派发：
- **Prompt**：brief + review package + spec 约束
- **指令**：
  1. 读取 brief 文件
  2. 读取 review package（diff）
  3. 两阶段审查：
     - **阶段 A：Spec 合规性** — 实现是否满足 spec 要求
     - **阶段 B：代码质量** — bug、安全问题、性能问题
     - **阶段 C：TDD 合规** — 测试是否充分
  4. 输出 Review JSON 到 `.specpow/changes/{change}/sdd/review-result.json`：
     ```json
     {
       "specCompliant": true/false,
       "qualityApproved": true/false,
       "findings": [
         {
           "id": "F1",
           "severity": "critical|important|minor",
           "description": "...",
           "file": "src/foo.ts",
           "line": 42,
           "isLoadBearing": false
         }
       ],
       "cannotVerify": ["..."]
     }
     ```
     **注意**：初始审查不输出 `addressed` 字段（由重审者在修复循环中填充）。

#### 2f. 运行测试

执行项目测试：
```bash
# 检测包管理器并运行测试
if [ -f pnpm-lock.yaml ]; then
  pnpm test --silent
elif [ -f yarn.lock ]; then
  yarn test --silent
else
  npm test --silent
fi
```

记录测试结果：通过/失败。

#### 2g. 分析审查结果

读取 review JSON，判定：
- `specCompliant === true && qualityApproved === true && tests passed` → **PASS**
  - 记录到 Ledger：`Task {N}: complete (commits {BASE}..{HEAD}, review clean)`
  - 进入下一任务
- `findings.length > 0 || tests failed` → **需要修复**，进入修复循环

### 步骤 3：修复循环（最多 5 轮）

每轮：

1. **派发实现者修复（复用原始 brief）**
   - Brief 路径不变：`.specpow/changes/{change}/sdd/task-{N}-brief.md`（不修改 brief 文件）
   - Open findings 通过指令传递给实现者，不写入 brief 文件
   - **模型升级**：第 4-5 轮使用比当前高一级模型
   - **指令**：修复 findings → 写 Report JSON 到 `task-{N}-report.md.fix-{R}`

2. **生成修复 diff**
   ```bash
   FIX_BASE=$(git rev-parse HEAD)
   # 实现者修复后...
   FIX_HEAD=$(git rev-parse HEAD)
   git diff ${FIX_BASE}..${FIX_HEAD} > .specpow/changes/{change}/sdd/review-package.md
   ```

3. **派发重审者（范围限定）**
   - **只审查修复部分**，不重新审查整个任务
   - **指令**：对每个 finding 判定 `addressed: true/false`
   - 输出更新后的 review JSON 到 `.specpow/changes/{change}/sdd/re-review-result.json`

4. **运行测试**

5. **分析结果**
   - 所有 findings addressed + tests passed → **PASS**
   - 仍有 open findings → 继续下一轮

6. **记录到 Ledger**
   ```
   Task {N}: fix round {R}/5 ({A} addressed, {O} open — {finding1_summary}; {finding2_summary}; commits {BASE}..{HEAD})
   ```

**断路器**：5 轮后仍未通过 → 对每个 finding 判定：
- `isLoadBearing === false` → **park**（延后，记录到 Ledger）
- `isLoadBearing === true` → **block**（阻塞，任务标记为 BLOCKED）

### 步骤 4：完成

所有任务完成后，输出总结：
```
✅ SDD 执行完成
- 完成任务：X/Y
- 阻塞任务：Z
- 停放发现：N（已记录到 Ledger）
```

## 并行执行模式

当用户指定 `--parallel` 或任务数量 ≥ 3 且无强依赖时，可启用并行执行。

### 前置条件

- 任务清单已读取
- 依赖分析完成（参考 `buildParallelLayers` 逻辑）

### 执行流程

#### 1. 依赖分析与分层

分析任务依赖关系，构建并行层：
- **文件级依赖**：多个任务修改同一文件 → 顺序执行
- **逻辑级依赖**：tasks.md 中显式声明的依赖
- **分层结果**：每层内的任务彼此独立，可并行执行

```
示例：
- 层 1: [T1, T2, T3] — 无依赖，可并行
- 层 2: [T4] — 依赖 T1 的输出
- 层 3: [T5, T6] — 无依赖，可并行
```

#### 2. 逐层并行执行

对每一层：

##### 2a. 为每个任务创建 Git Worktree

```bash
# 为每个任务创建独立 worktree
BASE_COMMIT=$(git rev-parse HEAD)
BRANCH_NAME="specpow-parallel-{TASK_NUM}-{TIMESTAMP}"
WORKTREE_PATH=".specpow/changes/{change}/sdd/.worktrees/task-{TASK_NUM}"

git worktree add -b "$BRANCH_NAME" "$WORKTREE_PATH" "$BASE_COMMIT"
```

**关键**：
- 每个任务在独立的 worktree 中工作，消除并行竞态
- worktree 拥有独立的 HEAD 和工作目录
- 所有文件编辑和 git 操作必须在 worktree 中执行

##### 2b. 并行派发实现者子代理

使用宿主原生 subagent 工具**同时**派发多个实现者：

```
对层内的每个任务：
  派发子代理（isolation: "worktree"）：
    - prompt: 读取 brief + TDD 指令 + spec 约束
    - 指令：在 worktree 中工作，完成后写 report
    - 模型选择：参考串行模式的模型选择表
```

**并行派发示例**（Claude Code）：
```
同时发起多个 Agent 调用：
- Agent 1: "Task 1 in worktree .specpow/changes/{change}/sdd/.worktrees/task-1"
- Agent 2: "Task 2 in worktree .specpow/changes/{change}/sdd/.worktrees/task-2"
- Agent 3: "Task 3 in worktree .specpow/changes/{change}/sdd/.worktrees/task-3"
```

##### 2c. 等待所有子代理完成

所有子代理完成后，检查各自的 report 文件。

##### 2d. 顺序合并分支

```bash
# 按任务编号顺序合并
for TASK_NUM in 1 2 3; do
  BRANCH="specpow-parallel-${TASK_NUM}-xxx"
  git merge "$BRANCH" --no-edit
  
  # 检查冲突
  if [ $? -ne 0 ]; then
    echo "冲突：任务 $TASK_NUM 合并失败"
    # 记录到 Ledger
  fi
done
```

##### 2e. 冲突检测

检查哪些文件被多个任务修改：
```bash
# 对每个完成的任务，获取变更文件列表
for TASK_NUM in 1 2 3; do
  git diff --name-only "$BASE_COMMIT".."$HEAD_COMMIT"
done

# 如果同一文件出现在多个任务的变更列表中 → 冲突
```

##### 2f. 清理 Worktree

```bash
# 删除 worktree 和分支
git worktree remove ".specpow/changes/{change}/sdd/.worktrees/task-{TASK_NUM}" --force
git branch -D "specpow-parallel-{TASK_NUM}-xxx"
```

##### 2g. 运行集成测试

所有任务合并后，运行完整测试套件：
```bash
pnpm test --silent
```

##### 2h. 记录到 Ledger

```
Layer {L}: complete ({N} tasks merged, {C} conflicts detected)
```

#### 3. 层间串行

前一层合并完成后，才开始下一层。这确保了依赖关系的正确性。

### 并行执行的注意事项

1. **绝不并行修改同一文件** — 依赖分析必须准确
2. **合并后必须运行完整测试** — 并行执行可能引入集成问题
3. **冲突是并行代价** — 显式报告冲突，而非静默丢失
4. **Worktree 清理必须彻底** — 即使任务失败也要清理
5. **断路器保护** — 如果一层中有 ≥ 50% 任务失败，停止后续层

### 何时使用并行模式

| 场景 | 推荐模式 |
|------|----------|
| 3+ 个独立任务，无文件重叠 | 并行 |
| 任务间有强依赖 | 串行 |
| CI/CD 自动化 | 并行（节省时间） |
| 交互式开发，需要实时反馈 | 串行（更易调试） |
| 多文件非依赖变更 | 并行 |

## Ledger 记录格式

每完成一个操作，**追加一行**到 `.specpow/changes/{change}/sdd/progress.md`。
格式为**扁平日志行**（不是结构化 markdown），ledger.ts 用正则解析这些行。

首行固定为：
```
# SDD ledger — plan: {planFile}
```

后续追加的日志行格式：

```
Task {N}: complete (commits {BASE}..{HEAD}, review clean)
Task {N}: complete (commits {BASE}..{HEAD}, review with parked)
Task {N}: fix round {R}/{MAX} ({A} addressed, {O} open — {summary1}; {summary2}; commits {RANGE})
Task {N}: BLOCKED — {reason}
Task {N}: parked — {description} — ruling: {ruling}
Task {N}: minor (deferred): {description}
```

**注意**：
- 每行独立，不分组、不嵌套
- `review clean` 表示审查通过无停放；`review with parked` 表示有停放发现
- fix round 行中的 summaries 用分号分隔，每个 summary 对应一个 open finding 的描述
- `{MAX}` 来自配置 `sdd.maxFixRounds`（默认 5）

## 关键原则

1. **文件即接口** — 所有产物通过文件传递，不占用上下文
2. **信任 Ledger** — 断点续跑时读取 Ledger，不信任记忆
3. **模型升级** — 修复轮次 4-5 升级模型，避免卡死
4. **范围限定重审** — 修复后只审查修复部分，提高效率
5. **断路器保护** — 5 轮后强制判定，避免无限循环
