# 📋 JARVIS 规则系统最佳实践

本指南介绍如何创建、使用和管理 JARVIS 规则系统，帮助开发者编写高质量、可维护的规则文档。

## ✨ 什么是规则系统

JARVIS 规则系统是一套基于 Markdown 的规范化指令集合，用于指导 Agent 在代码生成、代码审查、重构等任务中遵循统一的标准和最佳实践。

### 规则系统的价值

- **统一标准**：确保不同 Agent 的输出风格一致
- **质量保证**：内置检查清单，减少代码缺陷
- **知识传承**：将最佳实践文档化，便于团队共享
- **灵活扩展**：可根据项目需求自定义规则
- **动态渲染**：支持 Jinja2 模板语法，实现规则内容的动态化

---

## 📚 现有规则概览

JARVIS 内置了以下规则，位于 `builtin/rules/` 和 `builtin/rules/testing/` 目录：

### 架构设计

| 规则文件                | 用途          | 适用场景       |
| ----------------------- | ------------- | -------------- |
| `solid.md`              | SOLID设计原则 | 面向对象设计   |
| `clean_architecture.md` | 整洁架构      | 架构设计       |
| `clean_code.md`         | 整洁代码规范  | 代码生成、重构 |

### 开发流程

| 规则文件            | 用途         | 适用场景     |
| ------------------- | ------------ | ------------ |
| `sdd.md`         | Spec驱动开发 | 设计文档编写 |
| `tdd.md`         | 测试驱动开发 | 测试代码生成 |
| `refactoring.md` | 重构指南     | 代码重构任务 |

### 代码质量

| 规则文件           | 用途         | 适用场景     |
| ------------------ | ------------ | ------------ |
| `code_review.md`   | 代码审查标准 | 代码审查任务 |
| `documentation.md` | 文档编写规范 | 文档生成     |

### 安全规范

| 规则文件      | 用途         | 适用场景     |
| ------------- | ------------ | ------------ |
| `security.md` | 安全编码标准 | 安全相关代码 |

### 性能优化指南

| 规则文件              | 用途         | 适用场景     |
| --------------------- | ------------ | ------------ |
| `performance.md`      | 性能优化指南 | 性能敏感代码 |
| `rust_performance.md` | Rust性能优化 | Rust代码优化 |

### UI设计

| 规则文件             | 用途            | 适用场景     |
| -------------------- | --------------- | ------------ |
| `ios-dark-theme.md`  | Zen-iOS暗色主题 | 前端界面开发 |
| `ios-light-theme.md` | Zen-iOS亮色主题 | 前端界面开发 |

### 工具配置

| 规则文件               | 用途         | 适用场景     |
| ---------------------- | ------------ | ------------ |
| `ignore_all_alerts.md` | 忽略所有告警 | 特殊场景使用 |

### 测试规范

| 规则文件             | 用途                          | 适用场景       |
| -------------------- | ----------------------------- | -------------- |
| `cpp_test.md`        | C/C++测试指南                 | C/C++代码测试  |
| `go_test.md`         | Go测试指南                    | Go代码测试     |
| `javascript_test.md` | JavaScript/TypeScript测试指南 | JS/TS代码测试  |
| `java_test.md`       | Java测试指南                  | Java代码测试   |
| `php_test.md`        | PHP测试指南                   | PHP代码测试    |
| `python_test.md`     | Python测试指南                | Python代码测试 |
| `ruby_test.md`       | Ruby测试指南                  | Ruby代码测试   |
| `rust_test.md`       | Rust测试指南                  | Rust代码测试   |

---

## 🚀 如何使用规则

### 规则的存储位置

JARVIS 支持从多个位置加载规则，按优先级从高到低：

1. **中心规则仓库**（最高优先级）
   - 位置：通过配置 `central_rules_repo` 指定
   - 支持本地目录或 Git 仓库 URL
   - 如果有同名规则，以中心仓库为准

2. **项目规则目录**
   - 位置：`<项目根目录>/.jarvis/rules/`
   - 存储项目特定的规则文件（`.md` 格式）

3. **配置的规则目录**
   - 位置：通过 `rules_load_dirs` 配置项指定
   - 支持多个目录，按配置顺序加载

4. **全局规则目录**
   - 位置：`~/.jarvis/rules/`
   - 存储全局共享的规则文件

5. **内置规则目录**
   - 位置：`builtin/rules/` 和 `builtin/rules/testing/`
   - JARVIS 自带的规则集

6. **rules.yaml 文件中的规则**
   - 可以在 `rules.yaml` 中定义命名规则
   - YAML 格式，键为规则名称，值为规则内容

### 规则的加载方式

#### 方式 1：通过 `--rule-names` 参数指定

```bash
# 使用单个规则
jarvis code --rule-names clean_code

# 使用多个规则（逗号分隔）
jarvis code --rule-names clean_code,security,performance

# 组合使用项目规则和内置规则
jarvis code --rule-names my_project_rule,clean_code
```

#### 方式 2：通过项目规则文件

创建 `.jarvis/rule` 文件，内容将自动加载：

```markdown
# .jarvis/rule

# 这是一个全局规则，对所有任务生效

你必须遵守以下原则：

- 代码必须符合 PEP 8 规范
- 所有公共函数必须有类型注解
- 必须编写单元测试
```

#### 方式 3：通过全局规则文件

创建 `~/.jarvis/rule` 文件，对所有项目生效：

```markdown
# ~/.jarvis/rule

# 全局默认规则

使用 Python 编写代码时：

- 必须使用 `f-strings` 进行字符串格式化
- 禁止使用 `print()` 语句（使用 logging 模块）
```

#### 方式 4：通过 rules.yaml 定义命名规则

创建 `rules.yaml` 文件，定义可按名称引用的规则：

```yaml
# .jarvis/rules.yaml 或 ~/.jarvis/rules.yaml
python_best_practices: |
  # Python 最佳实践规则

  **命名规范：**
  - 变量名使用 snake_case
  - 类名使用 PascalCase
  - 常量使用 UPPER_CASE

cpp_memory_safety: |
  # C++ 内存安全规则

  **必须：**
  - 使用智能指针管理内存
  - 禁止使用裸指针
  - 必须使用 RAII 模式
```

使用时通过名称引用：

```bash
jarvis code --rule-names python_best_practices
```

#### 方式 5：使用 @ 交互式增加规则

在交互式输入中输入 `@` 符号即可触发规则补全功能，快速选择并插入所需的规则。

**使用步骤：**

1. **触发补全**：在交互式输入过程中输入 `@` 符号
2. **浏览规则**：系统自动显示所有可用的规则列表，包括：
   - 内置规则（`builtin/rules/`）
   - 项目规则（`.jarvis/rules/`）
   - YAML 定义规则（`rules.yaml`）
   - 全局规则（`~/.jarvis/rules/`）
3. **选择规则**：使用上下键或鼠标选择所需的规则
4. **自动注入**：确认选择后，规则内容自动插入到输入中

**补全优先级：**

规则按以下顺序显示和查找：

1. 中心规则仓库（最高优先级）
2. 项目规则目录（`.jarvis/rules/`）
3. 项目 `rules.yaml` 文件
4. 配置的规则目录
5. 全局规则目录（`~/.jarvis/rules/`）
6. 内置规则目录（`builtin/rules/`）

**支持的操作：**

- **实时搜索**：输入规则名称的部分字符可快速过滤规则列表
- **多选插入**：可以选择多个规则依次插入
- **预览内容**：部分系统支持在插入前预览规则内容
- **快捷键**：支持使用 `Tab` 或 `Enter` 快速确认选择

**使用场景：**

- ✅ 需要快速切换不同规则集时
- ✅ 不记得规则具体名称时
- ✅ 想要组合多个规则使用时
- ✅ 临时需要添加额外规则时
- ✅ 交互式开发调试过程中

**方式对比：**

| 方式                | 优点         | 缺点       | 适用场景     |
| ------------------- | ------------ | ---------- | ------------ |
| `--rule-names` 参数 | 明确指定     | 需记住名称 | 脚本和CI/CD  |
| 项目规则文件        | 自动加载     | 仅单文件   | 项目固定规则 |
| 全局规则文件        | 所有项目生效 | 可能不适配 | 个人通用规范 |
| rules.yaml          | 集中管理复用 | 需预先定义 | 常用规则集   |
| @ 交互式            | 快捷灵活搜索 | 仅交互场景 | 临时需求     |

**注意事项：**

- `@` 补全功能仅在交互式模式下可用
- 补全列表会自动合并所有可用的规则源
- 同名规则时，优先级高的规则会覆盖优先级低的规则
- 如果规则文件较多，建议使用搜索功能快速定位

### 规则加载优先级详解

当指定多个规则来源时，系统按以下顺序合并规则：

1. **全局规则文件**（`~/.jarvis/rule`）
2. **项目规则文件**（`.jarvis/rule`）
3. **通过 `--rule-names` 指定的规则**

查找指定规则时，按以下顺序查找：

1. 中心规则仓库
2. 项目规则目录（`.jarvis/rules/`）
3. 项目 `rules.yaml` 文件
4. 配置的规则目录
5. 全局 `rules.yaml` 文件
6. 内置规则（最低优先级）

### 使用示例

#### 示例 1：代码审查时使用特定规则

```bash
# 只使用代码审查规则
jarvis review --rule-names code_review,security
```

#### 示例 2：重构时使用多个规则

```bash
# 组合使用重构规则和整洁代码规则
jarvis refactor --rule-names refactoring,clean_code
```

#### 示例 3：为特定项目配置专属规则

在项目根目录创建 `.jarvis/rules/my_project_rule.md`：

```markdown
# 我的项目规则

**项目特定要求：**

- 所有 API 函数必须返回统一格式：`{"code": 0, "data": {...}, "msg": ""}`
- 数据库操作必须在事务中执行
- 所有外部调用必须有超时设置（默认 30 秒）
```

使用时：

```bash
cd /path/to/my/project
jarvis code --rule-names my_project_rule,clean_code
```

---

## 🔧 规则占位符的使用

JARVIS 规则系统支持使用 **Jinja2 模板语法**，可以在规则文件中使用占位符，实现规则内容的动态化。

### 可用的占位符变量

| 变量名                  | 说明                     | 示例值                 |
| ----------------------- | ------------------------ | ---------------------- |
| `{{ current_dir }}`     | 当前工作目录（绝对路径） | `/home/user/myproject` |
| `{{ script_dir }}`      | 脚本所在目录             | `/path/to/jarvis/...`  |
| `{{ jarvis_data_dir }}` | jarvis 数据目录          | `~/.jarvis`            |
| `{{ jarvis_src_dir }}`  | jarvis 源码目录          | `/path/to/jarvis`      |
| `{{ git_root_dir }}`    | Git 仓库根目录           | `/home/user/myproject` |
| `{{ rule_file_dir }}`   | 规则文件所在目录         | `/home/user/...`       |

### Jinja2 基本语法

#### 变量输出

```jinja2
{{ variable_name }}
```

示例：

```markdown
# 项目根目录是：{{ git_root_dir }}

**要求：**

- 配置文件必须放在 `{{ git_root_dir }}/config/` 目录下
- 测试文件必须放在 `{{ git_root_dir }}/tests/` 目录下
```

渲染后：

```markdown
# 项目根目录是：/home/user/myproject

**要求：**

- 配置文件必须放在 `/home/user/myproject/config/` 目录下
- 测试文件必须放在 `/home/user/myproject/tests/` 目录下
```

#### 条件判断

```markdown
{% if condition %}
内容
{% endif %}
```

示例：

```markdown
{% if git_root_dir != current_dir %}
**注意：** 你当前不在项目根目录，请切换到 {{ git_root_dir }} 再执行操作
{% endif %}
```

#### 循环

```markdown
{% for item in list %}

- {{ item }}
  {% endfor %}
```

#### 注释

```markdown
{# 这是一个注释 #}
```

### 实际应用示例

#### 示例 1：引用项目特定路径

```markdown
# 项目文件组织规范

**必须遵守的目录结构：**

配置文件：`{{ git_root_dir }}/config/`
源代码：`{{ git_root_dir }}/src/`
测试代码：`{{ git_root_dir }}/tests/`
文档：`{{ git_root_dir }}/docs/`

**要求：**

- 所有源代码文件必须放在 `{{ git_root_dir }}/src/` 目录下
- 测试文件必须放在 `{{ git_root_dir }}/tests/` 目录下
- 配置文件必须放在 `{{ git_root_dir }}/config/` 目录下
```

#### 示例 2：根据环境动态生成规则

```markdown
# 环境特定的配置要求

**配置文件位置：**

主配置：`{{ jarvis_data_dir }}/config/main.yaml`

{% if rule_file_dir == git_root_dir + "/.jarvis/rules" %}
**项目特定配置：**

- 项目配置文件：`{{ git_root_dir }}/.jarvis/config.yaml`
- 使用项目配置覆盖全局配置
  {% endif %}
```

#### 示例 3：路径规范化

```markdown
# 使用 git_root_dir 确保路径一致性

**日志文件位置：**

日志必须写入：`{{ git_root_dir }}/logs/app.log`

**临时文件位置：**

临时文件必须放在：`{{ git_root_dir }}/tmp/`

**禁止事项：**

- 禁止在 `{{ git_root_dir }}/src/` 目录中存放临时文件
- 禁止使用硬编码路径（如 `/tmp/` 或 `/var/log/`）
```

### 占位符使用的最佳实践

1. **优先使用 `git_root_dir`**：确保路径始终相对于项目根目录
2. **避免硬编码路径**：使用占位符代替绝对路径
3. **合理使用条件判断**：根据不同环境生成不同规则
4. **添加注释**：在复杂的 Jinja2 语法旁添加注释说明
5. **测试渲染结果**：创建规则后测试占位符是否正确渲染

### 常见问题

**Q：占位符渲染失败会怎样？**

A：如果 Jinja2 渲染失败（如语法错误），系统会返回原始内容，不会影响规则加载。

**Q：可以在规则文件中定义自己的变量吗？**

A：不能直接定义，但可以通过 Jinja2 的 `set` 语句在模板内定义临时变量。

**Q：占位符会递归渲染吗？**

A：不会，每个规则文件只渲染一次。

---

## 📝 规则文件格式规范

### 基本结构

规则文件采用 Markdown 格式，推荐以下结构：

````markdown
# 规则标题

## 引言/背景

简要说明规则的用途和适用场景。

## 核心原则

### 原则名称

**执行要求：**

- **必须**：强制要求
- **禁止**：禁止行为

## 详细规范

### 子章节

**检查项：**

- [ ] 检查点 1
- [ ] 检查点 2

## 代码示例

### ❌ 不好的实践

```python
# 错误示例代码
```
````

### ✅ 好的实践

```python
# 正确示例代码
```

## 检查清单

在完成任务前，你必须确认：

- [ ] 检查项 1

- [ ] 检查项 2

### 格式要求

1. **标题层级**：使用 `##` 作为顶级章节，`###` 作为子章节
2. **强调标记**：
   - **必须**：强制要求，使用粗体
   - **禁止**：禁止行为，使用粗体
   - 建议：推荐做法，使用粗体
3. **检查清单**：使用 `- [ ]` 格式，便于 Agent 逐项确认
4. **代码示例**：使用明确的标题区分好/坏实践，如 `❌ 不好的实践`、`✅ 好的实践`

---

## 🎯 编写规则的最佳实践

### 1. 明确性原则

**要求：**

- 使用清晰、无歧义的语言
- 避免使用模糊词汇（如"尽可能"、"适当"）
- 明确区分强制要求和推荐建议

**示例：**

❌ **不好的写法：**

```markdown
函数应该尽可能短一些
```

✅ **好的写法：**

```markdown
**必须**：函数长度不超过 20 行
```

### 2. 可操作性原则

**要求：**

- 每条规则都应该是可验证的
- 提供具体的判断标准
- 包含代码示例说明

**示例：**

```markdown
**命名要求：**

- 变量名必须清楚表达其用途
- 函数名必须清楚表达其功能
- 禁止使用无意义的变量名（如 `a`, `b`, `x`, `temp`）
```

### 3. 结构化原则

**要求：**

- 按照逻辑层次组织内容
- 相关内容集中在一起
- 使用章节标题清晰划分

**推荐结构：**

1. 核心原则（最高优先级）
2. 具体规范
3. 代码示例
4. 检查清单

### 4. 示例驱动

**要求：**

- 每条关键规范都应配有示例
- 使用"好的实践"和"不好的实践"对比
- 示例代码应简洁、易懂

---

## 📂 规则分类和组织

### 命名规范

规则文件命名应遵循以下原则：

- **小写字母**：使用小写字母和下划线
- **描述性**：文件名应清晰描述规则内容
- **一致性**：同类规则使用相同前缀

**示例：**

```text
clean_code.md        # 整洁代码规范
code_review.md       # 代码审查规范
rust_performance.md  # Rust 性能优化
```

### 分类原则

按规则的性质进行分类：

1. **通用规范**：适用于所有语言和场景（如 `clean_code.md`）
2. **语言特定**：针对特定语言的规范（如 `rust_performance.md`）
3. **任务特定**：针对特定任务的规范（如 `code_review.md`）
4. **领域特定**：针对特定领域的规范（如 `security.md`）

---

## 🚀 创建新规则的完整示例

### 场景：创建一个 Python 异常处理规则

#### 步骤 1：确定规则目标

目标：指导 Agent 正确处理 Python 异常

#### 步骤 2：创建规则文件

文件路径：`builtin/rules/python_exception_handling.md`

#### 步骤 3：编写规则内容

````markdown
# Python 异常处理规范

## 你必须遵守的核心原则

### 1. 明确捕获异常（必须遵守）

**执行要求：**

- **必须**：捕获具体的异常类型，避免使用裸的 `except:`
- **必须**：只捕获你能够处理的异常
- **禁止**：使用 `except:` 捕获所有异常
- **禁止**：捕获后不进行任何处理（pass）

**示例：**

❌ **不好的实践：**

```python
try:
    data = load_config()
except:
    pass
```
````

✅ **好的实践：**

```python
try:
    data = load_config()
except FileNotFoundError:
    logger.error(f"Config file not found: {config_path}")
    raise
except json.JSONDecodeError as e:
    logger.error(f"Invalid JSON format: {e}")
    raise
```

### 2. 使用 finally 清理资源

**执行要求：**

- **必须**：在 `finally` 块中释放资源
- **必须**：使用上下文管理器管理资源
- **禁止**：在 `except` 块中遗漏资源释放

**示例：**

```python
# 使用上下文管理器
with open('file.txt', 'r') as f:
    data = f.read()
    # 文件会自动关闭
```

### 3. 提供有意义的错误信息

**执行要求：**

- **必须**：在捕获异常时记录上下文信息
- **必须**：使用结构化日志记录异常详情
- **禁止**：抛出无意义的异常

## 异常处理检查清单

在提交代码前，你必须确认：

- [ ] 所有异常捕获都是具体的类型
- [ ] 没有使用裸的 `except:`
- [ ] 捕获的异常都进行了处理或重新抛出
- [ ] 资源正确释放（使用 `with` 或 `finally`）

- [ ] 异常信息包含足够的上下文

### 步骤 4：测试规则

通过让 Agent 参考该规则生成代码，验证规则的有效性。

---

## ❓ 常见问题和注意事项

### Q1：规则应该多详细？

**A：** 规则应该足够详细，但不要过度。

- ✅ 好的规则：定义清晰的边界和期望
- ❌ 过度的规则：列出所有可能的情况，使文档难以阅读

### Q2：如何处理规则的优先级？

**A：** 在规则文件内部使用"核心原则"章节标记最高优先级的内容。规则之间如果有冲突，应该通过版本号或覆盖机制解决。

### Q3：规则是否支持继承或组合？

**A：** 规则文件是独立的，但可以在规则中引用其他规则。例如，在 `rust_performance.md` 中可以引用 `clean_code.md` 的基本原则。

### Q4：如何更新已有规则？

**A：** 更新规则时应：

1. 保持向后兼容，或明确标注破坏性变更
2. 更新版本号（如果有）
3. 通知团队成员规则已更新
4. 提供迁移指南（如果有重大变更）

### Q5：规则文件可以包含其他语言的内容吗？

**A：** 规则文件主要使用 Markdown 编写，但可以包含任何语言的代码示例作为说明。

### Q6：如何调试规则加载问题？

**A：** 可以通过以下方式调试：

1. 检查规则文件路径是否正确
2. 确认规则文件名（不包含 `.md` 后缀）是否与 `--rule-names` 参数一致
3. 查看是否有 Jinja2 语法错误
4. 检查规则文件编码是否为 UTF-8

### Q7：多个规则有冲突怎么办？

**A：** 当多个规则有冲突时：

1. 后加载的规则会覆盖先加载的规则中的相同内容
2. 在 `--rule-names` 中，后指定的规则优先级更高
3. 建议在规则中明确标注优先级或使用条件判断避免冲突

---

## 📌 注意事项

1. **保持简洁**：规则文件应该简洁明了，避免冗长
2. **定期审查**：规则应该随着技术发展而更新
3. **团队共识**：规则的制定应该基于团队共识
4. **实际测试**：新规则应该在实践中验证有效性
5. **文档同步**：规则变更应该及时同步到相关文档
6. **编码规范**：规则文件必须使用 UTF-8 编码

---

## 🔗 相关资源

- [builtin/rules/](../../builtin/rules/) - 内置规则目录
- [builtin/rules/testing/](../../builtin/rules/testing/) - 内置测试规则目录
- [docs/jarvis_config.md](../jarvis_config.md) - 配置系统文档
- [builtin_rules.py](../../src/jarvis/jarvis_code_agent/builtin_rules.py) - 加载
- code_agent_rules.py - 管理

---

## 🤝 贡献

欢迎贡献新的规则或改进现有规则！在提交前请确保：

- 遵循本最佳实践指南
- 规则清晰、无歧义
- 包含充分的示例
- 通过实际测试验证
- 使用 UTF-8 编码
- 正确使用 Jinja2 占位符（如需）

---

## 📄 许可证

MIT License
