# Agent Note: 语义化 PR 标签分类体系

Status: implemented

[English](2026-07-25-semantic-pr-label-taxonomy.md) | 中文

## 问题

PR（Pull Request）需要传达两个不同的信号：它带来哪一类变更，以及会影响仓库中的哪些领域。一套扁平或命名宽泛的标签会混淆这两个问题，掩盖 `session`、`llm` 等不同领域的工作，也让评审人和自动化流程得到的输入缺乏有效信息。

仓库还会随时间发展出新的领域。如果把当前的领域标签视为封闭集合，未来的工作就只能归入不准确的标签或通用兜底标签。

## 决策

每项开放或已合并的 PR 都带有恰好一个类型标签，以及所有受到实质影响的领域标签。未合并即关闭的 PR 不属于持续维护的历史记录集合。其他管理用途的标签可以并存，但都不能满足这两个维度中的任一个。

### 类型

| 类型 | 含义 |
|---|---|
| `feature` | 新增行为或有意改变行为。 |
| `bug-fix` | 修正错误行为。 |
| `doc` | 以文档变更为主要意图。 |
| `testing` | 修改测试或测试基础设施，但不改变产品行为。 |
| `cleanup` | 在保持行为不变的前提下，维护或简化实现或仓库流程。 |

类型记录变更的主要意图：配套测试与文档并不会把一项功能或缺陷修复变成测试或文档变更。

领域记录仓库中的语义领域，而不是临时项目、归属关系或偶然触及的每条路径。领域标签不构成层级：一项 PR 修改不同契约时可以带有多个领域标签，但不能用一个总括标签和一个较窄标签重复描述同一项工作。

### 当前领域

当前的 46 个领域如下。分组名称仅用于提高列表的可读性；它们既不是标签，也不是分类体系中的另一个层级。

| 分组 | 领域 |
|---|---|
| agent（智能体）与模型 | `agent`, `agent-loop`, `session`, `llm`, `model-context`, `compaction`, `tools`, `persistence` |
| 编排 | `subagent`, `workflow`, `planning`, `tasks`, `schedule`, `telemetry`, `storage`, `workspace` |
| 能力 | `bash`, `subprocess`, `pty`, `filesystem`, `lsp`, `skills`, `web-search`, `code-mode`, `artifact`, `attachment`, `sandbox`, `mcp`, `hooks`, `cordis` |
| 接口 | `ui`, `gui`, `tui`, `acp`, `json-rpc`, `cli`, `python-sdk`, `vscode`, `website` |
| 仓库与发布 | `dev-infra`, `ci`, `build`, `dependencies`, `platform`, `i18n`, `release` |

`gui` 涵盖浏览器和 Electron 图形应用，包括独立的图形化开发者工具；`vscode` 仍表示编辑器扩展集成。`ui` 涵盖共享的跨接口命令、审批交互、呈现和应用启动；只有当 PR 还修改这项共享契约时，它才与 `gui`、`tui` 或某个协议领域并用。

`tasks` 负责与运行中进程绑定的后台工作，`schedule` 则负责持久化的定时作业。`tools` 负责通用的注册表契约、schema 契约和执行契约；具体能力只有在修改其中一项契约时才带有 `tools`。`attachment` 负责持久化的媒体引用和多模态输入传递，`artifact` 则负责模型声明的交付物标识和预览生命周期；二者都不会因实现包含工具或界面部分而借用 `tools` 或 `ui`。

标签名称以语义归属为准，而不是词面相似性。`hooks` 指 Claude Code 和 Codex 的 agent 桥接，而不是本地 Git 钩子；`platform` 指产品可移植性，而不是 CI 运行器选择；`build` 指编译、打包和已构建的包（package）产物，而不是文档生成器。

### 可扩展性

领域集合有意保持可扩展。当分类体系缺少一个会反复涉及且具有实际意义的仓库领域时，就新增领域；不要仅为一项 PR、临时项目、状态、个人或团队新增标签。当领域模型发生变化时，重命名、拆分或退役相应领域，同时更新本列表以及所有受影响的开放和已合并 PR。

类型集合保持精简，因为各类型互斥。新增类型的前提是存在一种当前五类无法表达的独立变更意图；类型不能用来替代领域。

## 曾考虑的替代方案

- **一套不区分维度的标签。** 不予采纳，因为类型与领域回答的是不同问题；两者混在一起时，存在一个维度的标签并不表示另一个维度也经过了考虑。
- **一套固定、封闭的领域集合。** 不予采纳，因为仓库领域会持续演变。封闭集合会以牺牲语义准确性为代价来维持拼写不变。
- **一个宽泛的 `core` 领域，或从包结构派生的标签。** 不予采纳，因为 `session`、`llm` 和 `agent` 等领域在跨越包边界时仍各自具有意义，而偶然涉及的文件路径并不是评审人或自动化流程所需的范围信息。
- **为浏览器和桌面端分别设置领域。** 不予采纳，因为浏览器交付和 Electron 打包共同呈现同一个图形客户端领域；拆开二者将按交付形态而非工作的语义进行分类。
- **以宽泛的实现领域替代语义领域。** 不予采纳，因为持久化的定时作业不是后台任务，附件不只是其来源接口或文件系统实现，产物也不只是声明它的工具或预览接口。
- **同一项契约同时使用总括领域与细分领域。** 不予采纳，因为重复标签只会虚增范围，不会增加信息。一项 PR 确实修改不同契约时，多个领域标签仍然合理。
- **每项 PR 恰好一个领域。** 不予采纳，因为一项内聚的变更可以合理地跨越多个领域；省略次要领域会隐藏受影响的契约。

## 后果

- 评审人和自动化流程获得一个稳定的意图信号，以及完整的语义范围。
- `gui` 查询会同时覆盖浏览器与桌面端交付，`ui` 查询则只涵盖共享的跨接口契约。
- `schedule`、`attachment` 与 `artifact` 查询直接对应各自领域，无需通过实现依赖近似归类。
- 选择标签仍然需要判断：路径和标题前缀可以提示领域，但不能替代阅读变更内容。
- 变更分类体系会产生维护工作。新增、重命名、拆分或移除领域时，需要更新本决策记录，并回填开放和已合并的 PR，使历史查询保持原有含义。
