# Tapd Iteration Analysis

> 迭代执行流水线需求分析阶段。通过 TAPD MCP stories_get 拉取迭代中所有需求详情， 将 description 字段（完整 Markdown 内容）直接保存为需求文档，基于 parent_id 字段自动识别父子关系和独立需求，从需求文档的"依赖关系"章节提取显式依赖进行 拓扑排序，确定实现顺序，更新迭代状态。

- Skill: `tencentblueking/tapd-iteration-analysis` (Agent Skill)
- Install (CLI): `npx skillmds@latest add tencentblueking/tapd-iteration-analysis`
- Raw SKILL.md: https://api.skillmd.com/api/skills/tencentblueking/tapd-iteration-analysis/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- Author: tencentblueking (https://skillmd.com/u/tencentblueking)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/tencentblueking/tapd-iteration-analysis

---


# 需求依赖分析与排序

## 前置条件

- `iteration-state.json` 已存在且 `status` 为 `initialized`
- 以下字段可读：`iteration_id`、`workspace_id`、`owner`

## 执行流程

### 1. 创建临时目录

在迭代目录下创建 `.tmp/` 用于存放需求原始信息。

**Linux / macOS:**
```bash
mkdir -p "specs/${VERSION}/.tmp"
```

**Windows (PowerShell):**
```powershell
New-Item -ItemType Directory -Force -Path "specs\$VERSION\.tmp" | Out-Null
```

### 2. 获取需求详情与识别父子关系

通过 TAPD MCP `stories_get` 获取迭代中所有需求并识别层级关系。

#### 2.1 拉取所有需求

调用 `stories_get`，传入 `workspace_id` 和 `iteration_id`，获取本迭代中所有需求详情。
注意设置 `limit` 为足够大的值（如 200）以确保获取全部需求，必要时翻页处理。

返回结果中每个需求包含以下关键字段：
- **`id`**：需求长 ID（19 位）
- **`name`**：需求标题
- **`description`**：需求详细描述，**是包含完整信息的 Markdown 格式内容**
- **`parent_id`**：父需求长 ID（无父需求时为空或 "0"）
- 其他字段：`status`、`priority`、`owner` 等

#### 2.2 保存需求文档

`description` 字段本身已是结构完整的 Markdown 内容（通常包含需求描述、验收条件、
依赖关系等章节），直接以 `{ID}.md` 为文件名保存到 `.tmp/` 目录即可，**无需额外
拼装或转换格式**。

保存规则：
1. 文件名：`{需求长ID}.md`（如 `1000000755129275824.md`）
2. 文件内容：必须完整写入 `description` 字段的原始 Markdown 内容
3. 所有需求统一保存，无论是父需求、子需求还是独立需求

#### 2.3 识别父子关系

基于 `stories_get` 返回结果中每个需求的 `parent_id` 字段（非文档内容），
结合 `.tmp/` 目录下已保存的文件列表，按以下规则分类：

| 分类 | 判定条件 | 说明 |
|------|---------|------|
| **子需求** | `parent_id` 非空且不为 "0" | 该需求归属于指定的父需求 |
| **父需求** | 自身 ID 被其他需求的 `parent_id` 引用 | 拥有至少一个子需求 |
| **独立需求** | 既没有 `parent_id`，也没有被其他需求引用为父 | 独立实现的需求 |
| **父需求未入迭代** | `parent_id` 指向的 ID 在 `.tmp/` 目录中找不到对应文件 | 该父需求未划入本迭代 |

**处理"父需求未入迭代"的情况**：当子需求的 `parent_id` 在 `.tmp/` 中找不到对应文件时，
说明父需求未被划入本迭代。此时将这些子需求按 `parent_id` 归组，视为同一父需求下的
子需求组，但在展示时标注"父需求 #${PARENT_ID} 未入迭代"。

#### 2.4 构建结构化关系

基于上述分类结果，构建本迭代的需求层级结构：

```
迭代需求结构：
├─ 父需求 A (#ID_A)           ← 父需求（本迭代内）
│  ├─ 子需求 A-1 (#ID_A1)
│  └─ 子需求 A-2 (#ID_A2)
├─ [父需求 #ID_X 未入迭代]     ← 父需求未划入本迭代
│  ├─ 子需求 X-1 (#ID_X1)
│  └─ 子需求 X-2 (#ID_X2)
└─ 独立需求 B (#ID_B)          ← 独立需求
```

### 3. 需求依赖分析

对需要实现的需求进行依赖分析，构建有向无环图（DAG）。

#### 3.0 加载背景知识

检查项目根目录下是否存在 `AGENTS.md`（或 `agents.md`），如果存在则读取其内容，
为后续依赖分析提供项目上下文。重点关注以下信息：

- **项目结构和模块划分**：帮助判断需求涉及哪些模块以及模块间的关系
- **架构分层设计**：帮助识别跨层/跨模块的技术依赖
- **技术栈信息**：帮助判断需求之间是否存在共享技术组件依赖

如果 `AGENTS.md` 不存在，跳过此步骤，后续依赖分析完全基于需求文档内容进行。

#### 3.1 确定分析范围

**父需求不参与依赖评估**。父需求的目标是通过子需求的实现来达成，因此：
- 父需求本身不进入 DAG
- 只对**子需求**和**独立需求**进行依赖分析
- 父需求仅作为分组信息保留在 `iteration-state.json` 的 `stories` 结构中

#### 3.2 提取显式依赖

依赖信息的首要来源是需求文档中的 **"依赖关系"章节**。`.tmp/` 下的 `{ID}.md` 文件
内容即为 TAPD `description` 字段的原始 Markdown，其中通常包含"依赖关系"章节。
逐一读取每个子需求和独立需求的文档，重点解析该章节：

1. **提取章节内容**：读取文档中"依赖关系"相关章节的内容（章节标题可能为
   `## 依赖关系`、`## 依赖` 或类似变体，需做模糊匹配）
2. **识别依赖目标**：从章节中提取被依赖的需求 ID（可能是长 ID 或短 ID 形式）
3. **验证依赖有效性**：确认被依赖的需求 ID 存在于本迭代的需求列表中
   - 依赖目标在本迭代内 → 记录为有效依赖边
   - 依赖目标不在本迭代内 → 记录但标注为外部依赖（不影响排序）

#### 3.3 识别技术依赖与业务依赖

在显式依赖基础上，**对所有子需求和独立需求**进一步分析技术依赖和业务依赖，
确保依赖关系的完整性。逐一读取 `.tmp/` 下的需求文档全文内容，识别需求间的
技术耦合和业务流程先后约束。具体的依赖类型判定条件见 `../../references/dependency-types.md`。

**分析策略**：
1. 综合阅读每个需求的完整描述，提取涉及的模块、接口、数据结构、业务流程等关键信息
2. **结合背景知识**：如果已加载 `AGENTS.md`，对照其中的模块划分和架构分层信息，
   判断需求是否涉及相同模块或存在跨层调用，补充仅从需求文档无法识别的隐式依赖
3. 两两比对需求间是否存在上述技术依赖或业务依赖
4. 对识别出的依赖关系标注类型（技术/业务）和具体原因
5. 与 3.2 中的显式依赖合并去重，形成完整的依赖关系集合

#### 3.4 构建 DAG 并拓扑排序

1. 将所有子需求和独立需求作为节点
2. 将 3.2 显式依赖和 3.3 技术/业务依赖的合并结果作为有向边
3. 检测是否存在环依赖，如有则提示用户确认并协助解除
4. 执行拓扑排序，确定实现先后顺序
5. 标注可并行实现的需求组（同一拓扑层级内的需求可并行）

### 4. 更新状态

将分析结果写入 `iteration-state.json`：

1. **`sequence`**：拓扑排序后的需求 ID 列表（仅包含子需求和独立需求，不含父需求）
2. **`all_parents`**：所有识别出的父需求 ID（含未入迭代的父需求 ID）
3. **`selected_story`**：初始化为空字符串，编排层在执行时设置为当前正在实现的需求 ID
4. **`stories`**：按父需求分组的层级结构
   - 有父需求的子需求 → 归入对应父需求下的 `children`
   - 独立需求 → 以自身 ID 作为 key，`children` 为空
5. 所有子需求和独立需求的 `phase` 设为 `initialized`
6. 更新迭代 `status` 为 `analyzed`

### 5. 展示分析结果

向用户展示需求层级结构和实现顺序：

```
迭代 ${ITERATION_NAME} 需求分析完成！

需求结构：
├─ 父需求: ${PARENT_NAME_1} (#${PARENT_ID_1})
│  ├─ ${CHILD_NAME_1} (#${CHILD_ID_1})
│  └─ ${CHILD_NAME_2} (#${CHILD_ID_2})
├─ [父需求 #${PARENT_ID_X} 未入迭代]
│  └─ ${CHILD_NAME_3} (#${CHILD_ID_3})
└─ 独立需求: ${STANDALONE_NAME} (#${STANDALONE_ID})

实现顺序（基于依赖关系拓扑排序）：
1. ${STORY_NAME_1} (#${ID_1}) — 无依赖
2. ${STORY_NAME_2} (#${ID_2}) — 依赖 #${ID_1}（显式依赖）
3. ${STORY_NAME_3} (#${ID_3}) — 依赖 #${ID_1}（技术依赖：共享模块）
4. ${STORY_NAME_4} (#${ID_4}) — 依赖 #${ID_2}（业务依赖：前置功能）| 可与 #${ID_3} 并行

共 ${TOTAL} 个需求（${PARENT_COUNT} 个父需求，${CHILD_COUNT} 个子需求，${STANDALONE_COUNT} 个独立需求）
可执行需求 ${EXEC_COUNT} 个，预计 ${PARALLEL_GROUPS} 个并行组。
```

（注：`selected_story` 字段由编排层在执行需求时动态设置，此阶段无需填充）

## 产出

- `.tmp/` 目录下所有需求的 `description` 原始 Markdown 文件（`{ID}.md` 格式）
- 父子关系与独立需求已完整识别
- `iteration-state.json` 中以下字段已填充：
  - `sequence`：拓扑排序后的可执行需求 ID 列表
  - `all_parents`：所有父需求 ID
  - `selected_story`：初始化为空字符串
  - `stories`：按父需求、独立需求分组的层级结构
- 所有子需求和独立需求的 `phase` 为 `initialized`
- 迭代 `status` 为 `analyzed`

