# CI migration-file-count 规则 (per-PR) vs CLAUDE.md (per-commit) 不一致

**日期**：2026-05-17
**触发场景**：PR #408 (FFAI Agent Phase 2) CI `quality-gates / migration-file-count` 失败

## 现象

CI 报错：
```
New migration directories: 8
❌ 一个 PR 最多包含一个新的迁移目录（CLAUDE.md 数据库规则）
```

但 CLAUDE.md 原文是 **per-commit**：
> 每次提交最多包含一个迁移文件：一个功能涉及多个 schema 变更时，合并为一个迁移文件；禁止一个提交中包含多个迁移文件。

**本 PR 8 个 migration 分散在 8 个 commit，每 commit 1 个，符合 CLAUDE.md per-commit 规则。**

但 `.gitea/workflows/quality-gates.yml::migration-file-count`:
```bash
CHANGED=$(git diff --name-only --diff-filter=A "origin/${BASE_REF}...HEAD")
COUNT=$(printf '%s\n' "$MIG_FILES" | awk -F/ '{print $4}' | sort -u | wc -l)
if [ "$COUNT" -gt 1 ]; then
  echo "❌ 一个 PR 最多包含一个新的迁移目录（CLAUDE.md 数据库规则）"
  exit 1
fi
```

CI 算 `origin/develop...HEAD` 的全部新 migration 文件数——**per-PR** 实现，错引 CLAUDE.md。

## 影响

- 多模块协同 PR 必然多 migration（本 PR Phase 2 = 5 新表 + 1 enum + 1 ALTER + 2 FK = 8 SQL）
- 走 per-commit 干净 history（每个 feature commit 自带其 migration），CI 阻断
- 团队不得不为合规走"合并 N migration 到 1 个 SQL"——破坏 commit 一一对应、增量 review 性

## 走法决策（PR #408 现场）

A. **合 N migration 为 1 个**（跟 CI 规则）：
   - 拼接 SQL 按依赖顺序（enum → CREATE TABLE → ALTER ADD COLUMN → ALTER ADD FK）
   - 删 N-1 个旧目录，保留最早 timestamp 作为合并产物名
   - 本地 dev / test DB `--force-reset` 重建（_prisma_migrations 表记录从 N 条变 1 条）
   - UAT / production 未 apply 不受影响
   - **风险**：commit 历史里仍有 N 个 SQL 文件创建轨迹，merge 后 git log 看每个 commit 仍含独立 .sql，但本地工作目录已合并

B. **修 CI workflow 改 per-commit**（跟 CLAUDE.md）：
   - 改成 `for commit in $(git rev-list base..head); do git show $commit | grep ^A | check; done`
   - 但 `.gitea/workflows/` 是高风险路径，按 CLAUDE.md「主题不同必拆 / 高风险路径单 PR」准则不应在功能 PR 改
   - 必须独立 ops PR 改

PR #408 选 A（用户决策）：合 8 migration 为 1 个，本地 force-reset 通过验证。

## 预防规则

**写 CI check 时严格对齐 CLAUDE.md 文本**：
- "每次提交最多 X" → per-commit 实现（loop commits）
- "一个 PR 最多 X" → per-PR 实现（base...HEAD diff）
- 错引会让团队执行错误规则、被无关阻断

**如果故意 per-PR（鼓励单一 schema 主题 PR）**：
- 改 CLAUDE.md 文本对应
- 加 escape hatch：label `multi-migration-ack` 或 env var `ALLOW_MULTI_MIGRATION=true` 绕过
- 文档化 "什么时候可以多个 migration"（如 PRD 已声明多模块协同的 phase 落地）

## 关联

- 跟 [[ai-review-incremental-convergence-loop]] 同源——单一 finding source（CI / 本地预 push / 远端 ai-review）规则未对齐会让"修一条 → 触发新一条"形成渐近循环。
