Files
ai-proj-helper/skills-req/req-test-gate-plugin/skills/convention-flow.md
John Qiu b9c808cce0 feat(req-test-gate): 集成 Harness Engineering 工程约束方法论
将项目级的 Ratchet/约定检测方法论融入 req-test-gate 技能,
通过 /req 流程三个节点自动触发(dev 环境检测、cr 约定建议、test Gate 0B),
无需手动记忆执行。

新增文档:harness-engineering.md、ratchet-pattern.md、convention-flow.md、
project-bootstrap.md 及 4 个模板(ratchet/convention 脚本、GATES.md、pre-commit)。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-26 11:34:42 +10:30

223 lines
8.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Convention Flow — 约定建立流程
## 核心理念
**每个 bug 都是一个建立约定的机会。** 修复 bug 后,立即将教训固化为自动化检测,防止同类问题再次出现。
## 流程总览
```
Step 1: 修 Bug → 标准修复,代码层面解决问题
Step 2: 文档化约定 → 写入 CLAUDE.md让 AI 和人都知道这条规则)
Step 3: 自动化检测 → 创建 scripts/check-*.sh让 CI 自动阻止违规)
Step 4: 记录追踪 → 创建【约定】任务关联需求(仅 /req cr 自动触发时)
```
> Step 1-3 是核心流程手动和自动都执行。Step 4 仅在 `/req cr` 自动触发时执行,用于在 ai-proj 中留痕。
### Step 1: 修 Bug
标准的 bug 修复流程。此步骤无特殊要求。
### Step 2: 文档化约定
在项目的 CLAUDE.md 中添加约定段落,格式参见 [harness-engineering.md](harness-engineering.md) 的「CLAUDE.md 约定文档格式」。
**必须包含**
- 原因描述(为什么这是个问题)
- 一句话规则
- 正例和反例代码
- 检查命令
### Step 3: 自动化检测
创建 `scripts/check-{name}.sh` 脚本:
1. 扫描代码库查找违反约定的模式
2. 输出违规文件和行号
3. 支持 `--ci` 模式(退出码 0/1
4. 零违规时输出 PASSED 消息
### Step 4: 记录追踪(自动触发时)
当 convention flow 由 `/req cr` 自动触发时,产出物必须关联到当前需求:
```
ai-proj task create --title "【约定】{约定名称}"
ai-proj req link --id <req_id> --task-ids <task_id> # linkRole=documentation
ai-proj create-and-attach --id <task_id> --content "..." # 约定详情文档
```
**约定详情文档内容**
```markdown
## 约定: {名称}
| 字段 | 值 |
|------|-----|
| 来源需求 | REQ-XXXX |
| 触发 bug | {bug 描述} |
| 根因模式 | {代码模式} |
| 策略 | {hard wall / ratchet(N)} |
| 现有违规 | {N} 处 |
### 产出物
- CLAUDE.md 约定段落: ✅ 已添加
- 检测脚本: `scripts/check-{name}.sh` ✅ 已创建
- 首次运行结果: PASS
### 约定规则
{规则内容,与 CLAUDE.md 中一致}
```
> 这样在需求归档时能看到:这个 bug 不仅被修了,还产出了一条防止复发的约定。
## Commit 策略
Convention flow 的产出物CLAUDE.md 修改 + `scripts/check-*.sh` 新脚本)**必须单独提交**,不与 bug fix 代码混在一起:
```bash
# 1. Bug fix 已经提交
git add src/...
git commit -m "fix: 修复 Modal 重叠导致弹窗无法关闭"
# 2. Convention 产出物单独提交
git add CLAUDE.md scripts/check-modal-safety.sh
git commit -m "chore: 建立 Modal 安全约定和自动检测"
```
**原因**
- bug fix 可能需要 cherry-pick 到其他分支,约定脚本不应跟着走
- 约定提交的 review 焦点不同(规则是否合理 vs 代码是否正确)
- `git log --oneline scripts/` 可以快速看到所有约定建立历史
## 可检测性判断
`/req cr` 自动触发时AI 必须先判断 bug 根因是否能自动检测。判断标准:
**可检测(建议约定)** — 根因是一个**代码模式**,能用 grep/regex 在源码中匹配:
| 模式类别 | 示例 | grep 可行性 |
|---------|------|------------|
| API 误用 | `Modal.success()` 后直接 `setState` | grep `Modal.success` + 上下文检查 |
| 禁止导入 | handler 直接 import database 层 | grep import 路径 |
| 缺失守卫 | SQL 拼接而非参数化查询 | grep 字符串拼接模式 |
| 遗漏回调 | Promise 无 `.catch()` | grep `.then(` 无配对 `.catch` |
| 硬编码 | 密钥/密码直接写在代码中 | grep 常见密钥模式 |
**不可检测(仅记录根因)** — 根因是**逻辑/设计问题**,代码形态上看不出来:
| 模式类别 | 示例 | 为什么不行 |
|---------|------|-----------|
| 算法错误 | 排序方向反了、边界条件漏了 | 代码语法正确,逻辑错误 |
| 业务规则遗漏 | 退款应该校验订单状态但没校验 | 缺失的代码无法被 grep |
| 竞态条件 | 两个请求并发修改同一资源 | 需要运行时才能暴露 |
| 配置错误 | 环境变量填错、超时值设太小 | 值的正确性取决于上下文 |
**快速判断法**:问自己「能不能写一条 grep 命令找到所有同类问题?」能 → 可检测,不能 → 不可检测。
## 选择策略
修完 bug 后,根据当前违规数量选择不同策略:
| 现有违规数 | 策略 | 脚本类型 | 说明 |
|-----------|------|---------|------|
| **0** | Hard wall | 纯检测脚本(有 → FAIL | 刚修完最后一个违规,或首次建立 |
| **1-10** | Ratchet + 排期清理 | Ratchet 脚本 + 基线 | 创建任务逐一清理遗留 |
| **>10** | Ratchet only | Ratchet 脚本 + 基线 | 不立即清理,仅防止恶化 |
| **不可计数** | 仅检测/告警 | 告警脚本exit 0 | 如"代码风格"类软约定 |
## 实例 1: Modal 安全规则
**Bug**Ant Design `Modal.success()` 非阻塞,后续 `setState` 立即执行导致两个 modal 重叠,第一个无法关闭。
**Step 1 — 修 Bug**
`setNextModalOpen(true)` 移入 `onOk` 回调。
**Step 2 — 文档化**
在 CLAUDE.md 添加:
```markdown
### Frontend: Modal 安全规则
Ant Design 的 `Modal.success()` / `Modal.info()` 是**非阻塞**调用。
**规则:`Modal.success/info/warning/error` 之后如果还有 UI 操作,必须放在 `onOk` 回调中。**
// WRONG — 两个 modal 同时弹出
Modal.success({ title: '成功' });
setNextModalOpen(true);
// CORRECT — 等用户确认后再打开
Modal.success({ title: '成功', onOk: () => setNextModalOpen(true) });
**检查命令**`./scripts/check-modal-safety.sh`
```
**Step 3 — 自动化**
创建 `scripts/check-modal-safety.sh`
- 扫描 `.tsx` 文件中的 `Modal.success/info/warning/error` 调用
- 检查 25 行内是否有 `onOk` 回调
- 如果没有且后续 20 行内有 `set*Open(true)`,标记为违规
- 策略:现有违规 = 0 → Hard wall
## 实例 2: 架构层级约束
**问题**Handler 直接调用 database 层,绕过 service 层导致业务逻辑散落。
**Step 1 — 识别问题**
发现 108 个 handler 直接 import database 的文件。
**Step 2 — 文档化**
在 CLAUDE.md 和 `docs/architecture/LAYER_RULES.md` 中描述依赖矩阵和正反示例。
**Step 3 — 自动化**
创建 `scripts/check-architecture.sh`ratchet 脚本):
- 5 条规则3 个 ratchet + 2 个 hard wall
- 基线记录各规则的当前违规数
- 策略:遗留 108 个 → Ratchet只能减不能增
## 执行流程
### 自动触发(`/req cr` + bug 类需求)
**触发条件**(满足任一):
- `category == bug`
- category 为空但标题含 `fix``修复``bug``问题``缺陷`
- category 为空但 description 含 `根因``复现步骤`
```
1. /req cr 五视角扫描完成后
2. 检测是否为 bug 类需求(按上述条件判断)
3. 分析本次 bug 的根因模式(从 git diff 提取)
4. 判断:根因是否可自动检测?(判断规则见上方「可检测性判断」)
- 不可检测 → 仅在 CR 报告记录根因,不建议约定 → 结束
- 可检测 → 继续下一步
5. 检查是否已有覆盖此模式的脚本:
- ls scripts/check-*.sh读取每个脚本的注释头# ... detects ...
- 已有覆盖 → CR 报告记录「已有约定: check-{name}.sh」→ 结束
- 无覆盖 → 继续下一步
6. 扫描代码库统计同类模式的现有数量N
7. AskUserQuestion按 N 值调整措辞):
- N=0: 「此 bug 模式已修复,当前代码无同类问题。建立约定可防止未来复发,是否建立?」
- N>0: 「代码库中还有 {N} 处同类模式。建立约定可防止恶化 + 逐步清理,是否建立?」
- 否 → 记录到 CR 报告「约定建议:用户跳过」
- 是 → 执行 convention flowStep 2 + Step 3 + Step 4
8. 约定产出物关联到当前需求Step 4
9. 约定检查结果写入 CR 报告
```
### 手动触发(`/harness convention [name]`
```
1. 询问约定名称和类别(如果未提供)
2. 分析刚修复的 bug提取约定规则
3. 扫描代码库统计现有违规数量
4. 根据违规数量选择策略
5. 生成 CLAUDE.md 约定段落
6. 生成 scripts/check-{name}.sh 脚本
7. 运行脚本验证(应该 PASS
8. 输出摘要:约定名称、策略、违规数、文件清单
```