# Spec 驱动开发 (SDD) 规则

## 你必须遵循的工作流程

### Spec-实现-验证循环（严格执行）

1. **📝 Spec 阶段（编写功能规范）**：
   - 在编写任何代码之前，必须先编写详细的功能规范（Spec）
   - Spec 必须清晰描述功能目标、输入输出、边界条件、异常处理
   - Spec 必须包含明确的验收标准（Acceptance Criteria）
   - Spec 必须经过评审和确认后才能进入实现阶段

2. **⚡ 实现阶段（基于规范编码）**：
   - 严格按照 Spec 的描述进行代码实现
   - 不得偏离 Spec 定义的功能边界和接口设计
   - 实现过程中遇到 Spec 不明确的地方，必须先更新 Spec 再继续实现
   - 编写代码时同时考虑如何验证 Spec 的验收标准

3. **✅ 验证阶段（验证符合规范）**：
   - 对照 Spec 验证实现的正确性
   - 确保所有验收标准都已满足
   - 运行测试、代码审查、文档检查等验证活动
   - 如果验证失败，必须回到实现或 Spec 阶段进行修正

## 你必须遵守的原则

### Spec 优先原则

- **禁止**：在没有 Spec 的情况下开始实现功能
- **必须**：每个新功能都有对应的规范文档
- **必须**：Spec 应该清晰、具体、可验证
- **必须**：Spec 应该包含完整的验收标准

### 规范完整性原则

- **必须**：Spec 必须包含功能描述（做什么）
- **必须**：Spec 必须包含接口定义（输入输出）
- **必须**：Spec 必须包含边界条件（edge cases）
- **必须**：Spec 必须包含异常处理（error cases）
- **必须**：Spec 必须包含验收标准（如何验证完成）

### 规范一致性原则

- **必须**：代码实现必须与 Spec 保持一致
- **禁止**：实现超出 Spec 范围的功能（除非更新 Spec）
- **必须**：代码变更时同步更新 Spec
- **禁止**：Spec 与代码不一致

## Spec 编写要求

### 1. 文件位置要求（必须遵守）

**位置规范：**

- **必须**：Spec 文件应放置在项目的 `.jarvis/spec/` 目录

**文件路径：**

```text
{{ git_root_dir }}/.jarvis/spec/<spec_name>.md
```

**变量说明：**

- `{{ git_root_dir }}`：当前 git 仓库的根目录

**命名规范：**

- **必须**：使用小写字母
- **必须**：使用下划线 `_` 分隔单词
- **必须**：使用 `.md` 后缀
- **禁止**：使用空格、连字符 `-` 或大写字母

**命名示例：**

- ✅ 正确：`user_auth_spec.md`, `data_processing_spec.md`
- ❌ 错误：`UserAuthSpec.md`, `user-auth-spec.md`

### 2. Spec 必须包含的内容

1. **功能概述**
   - 简要说明功能的目标和价值
   - 明确功能的使用场景

2. **接口定义**
   - 函数/方法的签名（参数类型、返回值类型）
   - API 端点的定义（路径、方法、请求/响应格式）
   - 类的公共接口（属性和方法）

3. **输入输出说明**
   - 所有参数的详细说明（类型、范围、约束）
   - 返回值的详细说明（类型、含义）
   - 可能抛出的异常或错误码

4. **功能行为**
   - 正常情况的处理逻辑
   - 边界条件的处理方式
   - 异常情况的处理策略
   - 性能要求（如适用）

5. **验收标准**
   - 明确的通过条件
   - 可验证的测试场景
   - 具体的验证方法

### 3. Spec 编写规范

- **必须**：使用清晰、简洁的语言
- **必须**：避免模糊的表述（如"尽可能快"、"合理的"）
- **必须**：使用具体的数值和范围
- **必须**：提供具体的示例
- **必须**：使用结构化的格式（如列表、表格）

## 实践指导

### 编写 Spec 时的思考方式

- 问自己："这个功能要解决什么问题？"而不是"这个功能如何实现？"
- 从用户角度思考功能需求，而不是从技术角度
- 明确功能的边界，什么在范围内，什么在范围外
- 考虑各种可能的输入场景（正常、边界、异常）

### Spec 编写最佳实践

- 使用用户故事格式（作为...我需要...以便...）
- 为每个验收标准编号，便于追踪
- 使用示例来说明复杂的需求
- 区分"必须"和"可选"的需求
- 考虑向后兼容性和可扩展性

### 发现 Spec 问题时的处理流程

1. 立即停止实现
2. 更新 Spec 文档，澄清或补充缺失的信息
3. 重新评审更新后的 Spec
4. 确认 Spec 完整后继续实现

## 代码示例

### ❌ 不好的实践（没有 Spec）

```python
# 直接开始写代码，没有规范文档
def process_data(data):
    result = []
    for item in data:
        if item > 0:
            result.append(item * 2)
    return result
```

### ✅ 好的实践（先写 Spec）

**Spec 文档：**

````markdown
# 数据处理功能规范

## 功能概述

对输入的数值列表进行过滤和转换，返回正数的两倍值。

## 接口定义

### 函数签名

```python
def filter_and_double_positive_numbers(numbers: list[int]) -> list[int]
```
````

### 参数说明

- `numbers`: 输入数值列表，可以为空

### 返回值说明

- 返回过滤后的正数两倍值列表
- 如果没有正数，返回空列表

### 异常说明

- 如果输入不是列表，抛出 TypeError
- 如果列表包含非数值元素，抛出 ValueError

## 功能行为

### 正常情况

- 输入 [1, 2, 3]，返回 [2, 4, 6]
- 输入 [-1, 0, 1]，返回 [2]

### 边界情况

- 输入空列表 []，返回 []
- 输入包含 0，0 不被视为正数，不处理

### 异常情况

- 输入非列表类型，抛出 TypeError
- 列表包含字符串等非数值元素，抛出 ValueError

## 验收标准

1. 能正确过滤正数并翻倍
2. 能正确处理空列表
3. 能正确处理包含 0 的列表
4. 能正确抛出类型错误
5. 能正确抛出数值错误

````markdown
**代码实现：**

```python
# 基于 Spec 实现
def filter_and_double_positive_numbers(numbers: list[int]) -> list[int]:
    """过滤正数并翻倍

    参数:
        numbers: 输入数值列表

    返回:
        过滤后的正数两倍值列表

    异常:
        TypeError: 如果输入不是列表
        ValueError: 如果列表包含非数值元素
    """
    if not isinstance(numbers, list):
        raise TypeError("Input must be a list")

    result = []
    for number in numbers:
        if not isinstance(number, (int, float)):
            raise ValueError("List must contain only numbers")
        if number > 0:
            result.append(number * 2)

    return result
```
````

## 执行检查清单

在开始实现功能前，你必须确认：

- [ ] 已编写完整的功能规范文档
- [ ] Spec 文件已放置在 `{{ git_root_dir }}/.jarvis/spec/` 目录
- [ ] Spec 文件命名符合规范（小写字母、下划线分隔、.md 后缀）
- [ ] Spec 包含功能概述和目标
- [ ] Spec 包含清晰的接口定义
- [ ] Spec 包含完整的输入输出说明
- [ ] Spec 包含边界条件和异常处理
- [ ] Spec 包含明确的验收标准
- [ ] Spec 已经过评审和确认

在实现功能时，你必须确认：

- [ ] 严格按照 Spec 进行实现
- [ ] 没有超出 Spec 范围的实现
- [ ] 遇到 Spec 不明确时先更新 Spec

在完成实现后，你必须确认：

- [ ] 所有验收标准都已满足
- [ ] 代码实现与 Spec 一致
- [ ] 已编写测试验证所有验收标准
- [ ] 文档与实现保持同步
- [ ] 代码已通过审查

**SDD 成功的标志：**

- 实现 = Spec（没有偏离）
- 验收 = 标准（全部通过）
- 文档 = 真实（反映现状）
