# CI 红灯 ≠ 阻塞合并：分清 required vs advisory check

> **日期**: 2026-05-13
> **类型**: 流程辨析

## 现象

PR #362 的 ai-review CI 失败：
```
API Error: 400 "This organization has been disabled."
```

第一反应可能是"我的 PR 有问题，不能合"，实际看了分支保护规则才发现 ai-review 不是 required check。

## 辨析步骤

判断 CI 红是否阻塞 PR 合并，三件事：

1. **看分支保护的 `required_status_checks`** — 红的 check 是否在列
   ```bash
   curl -sS -H "Authorization: token $GITEA_API_TOKEN" \
     "http://43.130.59.228/api/v1/repos/<org>/<repo>/branch_protections/<branch>" | \
     python3 -c "import json,sys; print(json.load(sys.stdin).get('status_check_contexts'))"
   ```
   返回空 `[]` → 没有任何 check 是必须的，PR 只看 `required_approvals`。

2. **看错误本身的来源** — 业务代码失败 vs 基础设施失败
   - 业务代码失败（lint / build / test）= PR 的问题，必须修
   - 基础设施失败（API key 失效、网络超时、容器拉取失败、第三方服务挂）= **不是 PR 的问题**

3. **看 CLAUDE.md / 项目文档** — 是否有"ai-review 暂未 required"等历史背景
   CLAUDE.md 写明 tracking issue #259："等 ai-review 升 required check 后再加 auto-merge"，意思就是当前 advisory。

## 行动模板

CI 红时不要默认开始改代码。先跑这两步：

```bash
# step 1: 看 PR mergeable 状态
curl -sS -H "Authorization: token $GITEA_API_TOKEN" \
  "http://43.130.59.228/api/v1/repos/<org>/<repo>/pulls/<num>" | \
  python3 -c "import json,sys; d=json.load(sys.stdin); print('mergeable:', d.get('mergeable'))"

# step 2: 看 required_status_checks
# （命令同上面"辨析步骤 1"）
```

`mergeable: True` + `required_status_checks: []` → 即使 CI 红，PR 可以合。

## 教训

**默认假设 CI 红 = PR 有问题，是浪费时间的反应**。先花 30 秒区分 required vs advisory + 业务错误 vs 基础设施错误，避免无效改代码。

适用于任何"看到红色就慌"的场景——deployment 红、test 红、scan 红、cost monitor 红，都先验证是不是 required 再投入修复时间。
