# Operations Runbook

维护动作主要围绕三类工作：同步目录、校验人工入口、发布站点。发布站点在实现上又拆成“触发 workflow”和“复用 workflow”两层。排障时先确定问题落在哪一层，再看对应产物。

## 工作流

当前主干里和维护直接相关的 workflow 文件有五个：

- `sync.yml`
- `deploy-pages.yml`
- `deploy-frontend.yml`
- `publish-site.yml`
- `validate-pr.yml`

它们的分工并不重叠。

| 工作流 | 负责什么 | 不负责什么 |
| --- | --- | --- |
| `sync.yml` | 同步上游、合并目录、更新 README、自动提交目录变化 | 发布站点、解释所有同步失败原因 |
| `deploy-pages.yml` | 在 `Weekly Sync` 成功后或手动触发站点发布 | 自己完成构建细节、重新同步目录 |
| `deploy-frontend.yml` | 在前端/目录/发布脚本相关路径变更后触发站点发布 | 自己完成构建细节、重新同步目录 |
| `publish-site.yml` | 作为复用 workflow 构建前端、生成静态 API、部署 GitHub Pages | 重新同步目录、决定何时触发发布 |
| `validate-pr.yml` | 校验 `catalog/**/curated.json` 的结构约束 | 覆盖全仓逻辑、验证前端或脚本行为 |

## `sync.yml`

当前配置支持定时和手动触发。主链路包括：

1. 恢复缓存。
2. 执行增量抓取和各类 `sync_*` 脚本。
3. 检查是否至少保留了部分类型数据。
4. 运行 `scripts/merge_index.py`。
5. 更新双语 README。
6. 有变更时自动提交。

这条流程的策略不是“任一步失败都整体失败”，而是“尽量产出”。现有配置里多个同步步骤和合并步骤带有 `continue-on-error: true`。

这意味着：

- 单一上游失败时，目录仍可能继续更新。
- 流程整体显示成功时，产物也可能只是部分完整。

看到成功，不等于所有上游都成功；看到 warning，也不等于本次产物完全不可用。

## `deploy-pages.yml`

这条流程在 `Weekly Sync` 成功后触发，也支持手动触发。它只负责把“同步完成”转换成一次站点发布调用，本身不做构建。

## `deploy-frontend.yml`

这条流程在 `main` 分支的前端、目录和发布脚本相关路径变更后触发，也支持手动触发。它只负责把“相关代码变更”转换成一次站点发布调用。

## `publish-site.yml`

站点发布链路消费的是仓库当前状态，不是实时重新拉取上游。需要注意的是，这条 workflow 本身只接受 `workflow_call`；真正的触发入口是前面的 `deploy-pages.yml` 和 `deploy-frontend.yml`。

当前流程会：

1. 生成 featured 数据。
2. 生成 `frontend/public/api/*` 前端消费数据。
3. 构建 `frontend/`。
4. 生成 `frontend/dist/api/v1/*` 静态 API 页面。
5. 部署 GitHub Pages。

因此，“站点没更新”不一定是同步问题，也可能是构建、API 生成或部署问题。

## `validate-pr.yml`

这条工作流只盯 `catalog/**/curated.json` 的改动。它调用 `scripts/validate_curated.py` 做基础结构校验。

这条流程的边界非常窄：

- 适合挡住明显格式错误。
- 不适合被当成全仓通用 CI。
- 不会验证脚本行为、前端行为、README 或 wiki 的正确性。

PR 变绿，只能说明 curated 入口没明显坏掉，不能说明整个仓库没问题。

## 日常检查

维护时优先看这几个结果面：

- 最近一次 `sync.yml` 是否产出异常
- `catalog/index.json` 是否更新
- README 统计是否同步刷新
- 站点是否完成发布

如果这四项都正常，绝大多数“仓库是不是坏了”的担忧都可以先排除。

## 排障顺序

排障时建议按层级走，不要按感觉跳文件。

1. 先判断问题是数据层、治理层、发布层，还是平台适配层。
2. 再找对应输入文件或 workflow。
3. 最后决定改 curated、改脚本、改工作流还是改文档。

这个顺序比“先打开自己最熟的文件再找理由”更可靠。

## 常见故障

### 条目没出现

先查：

1. 对应类型同步脚本有没有拉到。
2. `curated.json` 有没有补。
3. `merge_index.py` 是否把它去重掉。

这类问题大多数不是前端问题。

### 条目出现了，但字段不对

先查：

- 上游原始数据是不是就错了
- curated 有没有补这个字段
- 合并逻辑是否把该字段定义成补充字段

如果你期待 curated 覆盖一个本来不在覆盖范围里的字段，问题不在“脚本没跑”，而在“语义预期不对”。

### 同步成功，但目录明显残缺

先查 `sync.yml` 日志里哪些步骤失败了，但因为 `continue-on-error` 没有阻断主流程。

当前主干允许“部分失败、继续产出”，所以这类现象是架构边界，不是偶发怪事。

### 站点没更新

先区分：

- 同步没有产出新目录
- Pages 发布没有触发
- 前端构建失败
- 静态 API 生成异常

“站点没更新”不是一个根因，只是一个外部表现。

## 常见误操作

### 直接修改自动产物

直接改自动生成文件，下一轮同步通常会覆盖你的修改。

### 在前端层补数据问题

如果问题根源在目录数据，前端兼容只会把问题藏起来。

### 看到 warning 就判断流程不可用

当前同步链路本来就是“尽量产出”风格。warning 需要分辨是否污染主产物，而不是一概视为灾难。

### 把 PR 校验当成全仓验证

`validate-pr.yml` 只覆盖 curated 入口。它没有覆盖脚本、前端和站点发布。

## 什么时候停手，先写设计稿

以下情况不建议直接边修边想：

- 准备改 schema
- 准备改去重原则
- 准备新增上游同步机制
- 准备改变平台命令契约
- 准备让局部修复影响整个目录出口

这些都不再是“运维动作”，而是结构性变更。

## 什么时候可以直接修

以下情况通常可以直接修：

- curated 字段错误
- 校验逻辑明显漏判或误判
- README / wiki 内容过时
- workflow 中命令、路径、触发条件明显错误

前提只有两个：

- 影响范围明确
- 验证路径明确

## 维护边界

这个仓库的维护目标是：

- 保持目录结构稳定
- 提高目录信号质量
- 让发布链路持续可用

它的维护目标不是：

- 为第三方资源做无限兜底
- 把每条资源都手工运营成精品
- 对外承诺每次同步都绝对完整无误

维护边界不清，后面的排障标准也会一起失真。
